Engines vs. Plugins

I want to build some core re-usable functionality that can be used in
many different apps. I've heard a lot of rumblings in the rails
community when it comes to engines but besides appable_plugin it looks
like the best solution. Any advice on this one would be helpful.

Hi

AFAIK, the trend is towards plugins...

CCH
http://cch4rails.blogspot.com

Rails Engines has become more or less "standard" Rails plugin some
time ago (http://rails-engines.org/news/2007/01/03/engines-are-dead-
long-live-engines/), and are in my opinion great solution for complex
re-usable parts of an application: eg. Document model tied to a
DocumentController, tied to a Admin::DocumentController, complete with
presentation/administration views, form builders, helpers, etc. This
way you can drop some over and over re-used functionality into your
application.

I cannot find the "heated" discussion concerning complex plugins,
engines, former components, but the common agreement in the end was,
that when you want to re-use complex parts within your company, or
have some enclosed logical part, engines are great way to go.

I have used the new engines/plugins recently, and *loved* the auto-
magical way of injecting logic withing the application from the engine
app/models, app/controllers/, app/views etc. You can subclass or mix
in the logic from the engine in *very* transparent and convenient way.
And, most of all, it doesn't clash in any way with "your" Rails logic
in /app/.

See this check-list if you haven't already:
http://rails-engines.org/development/how-to-tell-when-the-engines-plugin-might-be-useful/.

Cheers,

Karel

Thanks for the input. I'll be less apprehensive to use engines. I was
hesitant to use engines because I've seen someone try to break down an
application in to several engines which were interdependent. It was a
mess. Since that I've seen various blog posts for and against engines.
But I feel I have a stronger view for engines now and how to use them.
Engines are problematic themselves but how you use them can be.

I was trying to find the discussions between DHH & others I was
reading when standing before decision how to implement an
administration system & interafce for websites, which I have to build
from time to time (where the front-end could be "regular" HTML/CSS, or
Flash website, etc) to post here, but I couldn't dig up any.

My experience has taught me, that DHH is absolutely right in saying
that one is rarely able to do an "abstract" logic satisfying all its
implementations. This is also one of the hottest issues in talks with
PHP developers -- they seem to be so fixed on this whole "modularity"
and "code re-usability" issues. And it's also substantially true when
implementing even light-weight content-management systems. The needs
of singular implementations differ quite a lot.

The wonderful thing about Rails is that it's just so easy to actually
*build* something -- do actually some programming, not implement some
XYZ_Auth module. And that's a great a thing. When I need a Project or
DownloadableAsset object, I can actually build the object custom-
tailored to the present need.

But let’s say I am developing administration system for a couple of
very similar projects. In my case, portfolio websites of designer,
architect friends. The Project object is quite homogenous across
multiple websites -- Project belongs_to :category,
has_many :documents, has_one :thumnbail. I need some transparent
authentization scheme. I need some basic CRUD user-management in the
administration system. And I would like to have them synchronized
across the project. From my point of view it’s only natural to
abstract this bare-bones logic (which is the some) into some re-usable
code. It certainly wouldn’t be much elegant to re-use the code by
copying & pasting. Never mind the frustration with some future
maintenance of a couple of these projects. (The important part is of
course the “bare-bones” part -- this should be done in true “You Ain’t
Gonna Need It” [http://en.wikipedia.org/wiki/You_Ain’t_Gonna_Need_It]
style.)

Rails Engines (or the current "engine type plugin" implementation)
seem to me to be the most enjoyable way of implementing that (*big*
thanx to James Adam!), because they have very transparent way of
injecting this logic into any application. I can inherit from the
MyWonderfulAdminApp::Admin::ProjectController class, I can add methods
& logic to it, or I can ignore it. I can use views from vendor/
my_wonderful_admin_app/app/views/admin/project, I can "over-load" only
some of them in app/views/project, or again completely ignore it. This
spanning of logic across models, controllers and views is the most
enjoyable thing on Engines from my point of view.

So maybe you'll find useful and "re-use" :slight_smile: some of my thinking in
your decision. I would certainly be interested in reading how others
think about this issue.

Cheers,

Karel

From my point of view it's only natural to
abstract this bare-bones logic (which is the some) into some re-usable
code.

Please ignore the (blahh) in parenthesis :slight_smile:

Karel

I was trying to find the discussions between DHH & others I was
reading when standing before decision how to implement an
administration system & interafce for websites, which I have to build
from time to time (where the front-end could be "regular" HTML/CSS, or
Flash website, etc) to post here, but I couldn't dig up any.

My experience has taught me, that DHH is absolutely right in saying
that one is rarely able to do an "abstract" logic satisfying all its
implementations.

I'm not convinced of that.

After having to do several auth systems I believe I came up with one that is about as universal as it can get, and with a framework that has good modularity skills, it's ready to roll in a new project with full UI (not just scaffolding) in 5-10 minutes. It evolved over a few years, and I've used it on many simple and complex projects now. It was written in another language, and I'm porting it to Rails now. It can be used as a simple binary you're in or you're not system, role-basd, ACL with dynamic permissions matrix, and even has dynamic data access filters (query modification on a per user basis). It has all the government style password management stuff which can be enabled feature by feature (password rolling, 3-strikes, auto passphrase detection, etc). More info here: http://www.pageblocks.org/ftrs/api_auth

I think it is quite possible to come up with one implementation that satifies the vast majority of implementations. It's just that it will have some extra stuff for some implementations... which I suspect DHH (and many XP/pragmatic purists) might say that such a system _doesn't_ satify an implementation where those extra aren't needed. But then doesn't Rails itself have a boatload of stuff I'll never need?

This is also one of the hottest issues in talks with
PHP developers -- they seem to be so fixed on this whole "modularity"
and "code re-usability" issues. And it's also substantially true when
implementing even light-weight content-management systems. The needs
of singular implementations differ quite a lot.

I'm not a PHP guy, but I am a fan of modularity. It saves a lot of time for certain realms of projects and developers. It's not beneficial for everyone though. Looking at 37 Signals projects, I can see why DHH didn't bother giving it a lot of thought, but I've worked a wide range of projects, and modularity is a big win in enough places that IMO, a framework should be able to to build modular and monolithic applications with the same ease. More info on how my framework approaches app organization: http://www.pageblocks.org/ftrs/api_site

So far to me, Rails seems to be quite cumbersome in the area of modularity which is a pity. Maybe I'll change my mind after I figure out how to make plugins and gems, but considering the extra effort it takes to do that, it's still a weakness IMO (especially for those who will always think creating plugins is too hard for them).

I think I have some ideas on how to organize and config Rails for the type of modularity I'm accustomed to, we'll see how close I can get.

The wonderful thing about Rails is that it's just so easy to actually
*build* something -- do actually some programming, not implement some
XYZ_Auth module. And that's a great a thing. When I need a Project or
DownloadableAsset object, I can actually build the object custom-
tailored to the present need.

True, but that can still be combined with an overall architecture that enables really good modularity. Really good IMO is being able to drag one folder (i.e. a news or articles section) from project X into Project Y, and have it just work with 5 mins of setup detail tweaking. From there of course there will be fine tuning to adapt to specific needs, but the core needs are all ready to go.

Not that I think devs should just be Leggo(R) assemblers of other people's modules, but if I write a news module, I want to be able to re-use it as easily as possible.

But let's say I am developing administration system for a couple of
very similar projects.... Rails Engines (or the current
"engine type plugin" implementation)
seem to me to be the most enjoyable way of implementing that (*big*
thanx to James Adam!), because they have very transparent way of
injecting this logic into any application. I can inherit from the
MyWonderfulAdminApp::Admin::ProjectController class, I can add methods
& logic to it, or I can ignore it. I can use views from vendor/
my_wonderful_admin_app/app/views/admin/project, I can "over-load" only
some of them in app/views/project, or again completely ignore it. This
spanning of logic across models, controllers and views is the most
enjoyable thing on Engines from my point of view.

Here's hoping I'll find it satisfying to work with as well, but wouldn't it be better if the the way you wrote your application code could be shared as a modular component w/o the extra gymnastics that creating a plugin requires? At the moment it looks cumbersome to develop something experimentally, polish it up in the normal app organization, then go through and completely reorganize it so it works as a plugin. If the two methods were one and the same, it would have been better.

Anyway, after having developed and using my own framework for many years now, it's certainly an interesting journey to use someone else's.

-- gw (www.railsdev.ws)

I think engines and plugins are two different thing, even though
engines are in design also plugins with benefits.

In my opinion, engines should be used when you have control over how
the code is re-used. Engines are good if you are developing multiple
Rails application that follows the same design pattern (heck, having
engines work as a gem is even better in this setup -- ahh plugems?).
And the application are developed internally or by a group of people
who all agree that the login mechanism should use the following
models, helpers, etc. I'm not a big fan of re-using views though,
other than partials accessed via helpers, that are also part of the
engines.

I think a lot of the mess happens when engines are not properly used,
and the dependency is not properly arranged. Note, that engines try to
mix controller and helper classes, while models in your app override
those in the engines (this is more on require/load path order). Having
multiple engines in your Rails app also increases the possibility of a
mess, unless you add a 'namespace' to your models or classes -- or
like i said, a group of people who agreed before hand how to avoid
naming conflicts.

On the other hand, using engines is not a good idea when distributing
code back to the community. It's just impossible to force everyone to
follow the same design, and it will just lead into confusion, which in
turn lead to disappointment about the 'engines'.

Now, there's also a lot of talk about engines bloating the
application. I think it's not the engines plugin that is bloating the
app; but rather the additional code in the engines the app is using,
adds to the bloat. :slight_smile: Including additional load paths.

Thanks!

Mark

Yes, but the key part is the "after having to do several ..." --
that's DHH's favourite theme of *extraction* abstract logic and
patterns, not "inventing" them in advance. You can learn a lot about
the desired logic and clean it very well in this process.

Making your own plugin is *just as trivial* as making your
application, and is a *very* strong point in Rails' favour. (As is
Rake in this context for example.)

The "drag-and-drop" re-use is very hard (if not impossible) to make
right. Rails plugin (engine if you like) can give you exactly this
functionality: a PressRelease model tied to a PressRelease controller
complete with front-end/admin views which you can build upon in your
application. (In fact, I am hoping to finish a lightweight website
administration system implemented just this way and release it in
couple of weeks.)

Everyones mileage vary strongly in these issues :), but the "extra
gymnastic" you talk about is a god-send exercise for me. From my
experience, computer code rarely meets the standard aesthetic criteria
of beauty ("nothing could be added or removed"), and is always subject
to more and more refactoring. I take the packaging of some code into a
plugin as an opportunity to improve it.

Cheers,

Karel

Every engine should be developed primarily as an "internal" tool and
put to test of fellow developers first. That's true. But when it
passes such "test of time", I can see no reason for not releasing it
for others to use or take ideas from. Code from different sources does
not necesarilly invoke any mess in the application (think 5+ plugins
in typical Rails app). In my experience, it's more a matter of
properly written code issue than plugins/engines, Rails architecture,
etc. issue..

Cheers,

Karel