Updated answer
I sum up all my findings on my blog, you better look there:
Old answer
I looked around for a solution for this too, and (for completeness' sake and also to point others into this direction) here is what I found.
As of Rails3.1, engines can easily be generated through the command rails plugin new my_plugin --full
. This generates the skeleton for an engine.
--full
means that the engine will be "merged" right into the including application, so that for example controllers should be directly accessible as if they were defined in the including app. This lets you e.g. have a helper file in my_engine/app/helpers/my_helper.rb
that will be merged right into your including app's app/helpers/my_helper.rb helper
.
There's another option --mountable
which creates a namespace for the engine so that its controllers etc. will never collide with the including application's ones. This results in e.g. a helper being in my_engine/app/helpers/my_engine/my_helper.rb
which won't collide with a helper app/helpers/my_helper.rb
in your including app.
Now the more interesting part:
Within the generated engine's test
folder, there's a dummy
folder which holds a complete Rails application! What's it for?
When you develop an engine, its functionalities are meant to work completely on their own, and it should also be tested completely on its own. So it's the "wrong" way to develop an engine "within" another Rails app (though this intuitively often will feel right when extracting existing functionalities from a Rails app into an engine), and so theoretically it is also not needed to reload an engine's code with every request to the including application.
The "right" way seems to be this: develop and test your engine, as if it were a full Rails app using the dummy
app! Therein you can do everything you can do in any "normal" Rails app, e.g. create controllers, models, views, etc. which use the functionalities the engine should provide. You also can normally start a server using rails s
in your test/dummy
directory and access the dummy app on localhost:3000
, and when running your tests, the dummy
app is automatically used for integration tests. Quite nice! :-)
You have to be careful where to put your stuff:
- Any functionality that is meant to be used within another Rails app goes into
my_engine/app
, while any functionality that is only needed to test the engine's functionality goes into test/dummy/app
.
Then afterwards you can easily load your engine in your main app's Gemfile
like this: gem 'my_engine', :path => 'path/to/my_engine'
or publish it to GitHub as a gem.
(One interesting thing (and to come back to this topic's subject) is that when I start the dummy's server, then all changes in the engine seem to be reflected within it! So somehow it seems to be possible to include an engine within a Rails app without caching it...? I don't know how this happens.)
So to sum up: an engine provides functionality that can stand completely on its own, so it should also be developed and tested on its own. Then, when it has reached a stable state, it can be included by any other app that needs its functionality.
Here's some resources I find useful:
I hope you find this answer useful. I'm still very new to engines in general, so if there's any wrong information, please tell me, and I'll correct it.