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

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