#149
Feb 16, 2009

Rails Engines

Rails 2.3 brings us much of the same functionality as the Rails Engines plugin. Learn how to embed one application into another in this episode.
Download (15.5 MB, 8:55)
alternative download for iPod & Apple TV (10.7 MB, 8:55)

Resources

gem install rails --source http://gems.rubyonrails.org
rails -v
script/generate plugin blogify
cd vendor/plugins/blogify
cp -R ~/code/blog/app .
mkdir config
cp ~/code/blog/config/routes.rb config
mkdir db
cp -R ~/code/blog/db/migrate db
rake db:migrate
rake blogify:sync
# vendor/plugins/blogify/tasks/blogify_tasks.rake
namespace :blogify do
  desc "Sync extra files from blogify plugin."
  task :sync do
    system "rsync -ruv vendor/plugins/blogify/db/migrate db"
    system "rsync -ruv vendor/plugins/blogify/public ."
  end
end

RSS Feed for Episode Comments 34 comments

1. Ubercow Feb 16, 2009 at 00:14

This looks very cool, thanks for the Railscast


2. Carl Feb 16, 2009 at 00:26

I'm downloading now. I wonder if this is due at all to Merb and Slices and the coming merger? It sounds sort of similar from your description.


3. George Feb 16, 2009 at 00:38

Any thoughts on how to handle authentication? Seems like that will be a sticky point for embedding applications together to play nice.


4. QuBiT Feb 16, 2009 at 02:00

if someone want to compare the "new" rails engine 2.3 with the "old" plugin to see what has changed and what is still missing, here is the link:

http://rails-engines.org/news/2009/02/02/engines-in-rails-2-3/

again, a really good screencast.


5. AdulteratedJedi Feb 16, 2009 at 07:32

Hmmm, I think I prefer the way merb does it with slices...


6. Moshi Feb 16, 2009 at 07:49

About migrations, why the plugin_migration generator is not used.

Isn't it available in Rails 2.3 ?
Maybe is it easier to work with rsync, why this choice ?

Anyway, thanks a lot for this great episode ! :)


7. Ryan Bates Feb 16, 2009 at 08:27

@George, you're right, authentication is tricky. I think it's best if one app handles the primary authentication and the other app simply extends the user class with the methods it needs.

@AdulteratedJedi, right, there's talk that this kind of thing will be much improved in Rails 3.

@Moshi, AFAIK plugin_migration isn't included in 2.3, it is only in the Rails Engine plugin. Rsync seemed like an easy enough solution, and you'll need to sync up the public files anyway so might as well do the migrations in the same way.


8. Jason Stahl Feb 16, 2009 at 10:00

Given that it's `system "rsync -ruv vendor/plugins/blogify/db/migrate db"` to move your migrations over.

Shouldn't it be `system "rsync -ruv vendor/plugins/blogify/public public"` and not `system "rsync -ruv vendor/plugins/blogify/public ."` to move the public files over?


9. Jason Stahl Feb 16, 2009 at 10:01

Oh wait. Nevermind... still too early for me.


10. Tony Feb 16, 2009 at 11:56

Another great screen cast! Can't wait to try it.

I'm not sure if Engines would work for my particular situation. Can anyone offer some advice for my current headache?

http://www.railsforum.com/viewtopic.php?id=23417

Thanks!


11. Rev. Dan Feb 16, 2009 at 11:58

Ryan, you are truly a prince amongst mortal men. I'm really impressed and inspired by your consistency in delivering highly interesting, relevant, and pragmatic screencasts. Just wow, man. And a huge high-five!


12. Shreyans Feb 16, 2009 at 12:51

Yet another great screen cast. I have one question though! What happens on moving some files to merged app, when there are already some files with same names?
It might be the case with image files in the public/images directory. And it is likely to have duplicates...


13. yanyu Feb 16, 2009 at 18:38

Personally, I prefer more desert (http://github.com/pivotal/desert/tree/master) than engines. Actually I have switched from engines to desert earlier. If you want to known why, please read the Brian Takita from pivotallabs's own comment about the desert framework (http://pivotallabs.com/users/brian/blog/articles/459-build-your-own-rails-plugin-platform-with-desert#1115). And I really like to use desert. Now I donot follow engines any more, and donot known which new features are coming into the new engines. If somebody knows, why should choose engines than desert, please tell me why. Thanks!


14. RailsCasts Fan Feb 17, 2009 at 02:26

Thanks ! Very good, like all your amazing screencasts ! :)


15. Geoffrey Grosenbach Feb 17, 2009 at 12:40

A plugin-based Rails generator would be a great way to create migrations and synchronize public assets for an engine.

Rails will handle file naming and conflicts automatically. And a simple file copying or migration generator is quite easy to write.

http://api.rubyonrails.org/classes/Rails/Generator/Base.html


16. Michael Feb 17, 2009 at 22:02

Excellent presentation as always. However, this "feature" seems pretty lackluster. It would be much cooler, and a lot more useful if there were items like "script/export engine" and "script/import engine". Or, perhaps even support "script/import engine --from existing_project". The inherent ability is very cool, but the mechanism by which to achieve the desired result -- eh...

Anyway, a continuous "thanks!" for spending so much time with this screencast. Keep up the amazing work!


17. RailsCasts Fan Feb 19, 2009 at 04:41

R2D2 is back! ^^


18. Henry Feb 20, 2009 at 14:54

I whipped up a plugin inspired from the original engines plugin that handles migrations (through rsync, like the screencast) and asset loading (more like the original plugin). Fork away ...

http://github.com/hpoydar/engines-helper


19. Jeffrey Lee Feb 21, 2009 at 20:01

The spam is out of control!

Great screencast. Would love to see a screencast on testing. I just cannot get started with it; there are so many variables.


20. Luca Guidi Feb 24, 2009 at 07:44

Hi, I just created a patch to run engines migrations with rake tasks, without sync/copy any file.

It adds db:migrate:engines and db:migrate:engines:down to run all the migrations from engines or for reset them.
You can also specify a single engine with the ENGINE env var.

This is the LH ticket: http://tinyurl.com/b2acxp


21. Luca Guidi Feb 28, 2009 at 10:23

I create a better version of the patch, and extracted into a plugin.

LH ticket: http://tinyurl.com/b2acxp

Plugin: http://github.com/jodosha/plugin_migrations/tree/master

Enjoy!


22. Eric Stockbridge Mar 05, 2009 at 16:41

I loved this episode, but have a couple issues with engines the way they are in 2.3.

1. I would like to have an easy way to handle the authentication across both apps, not sure if it is possible now.

2. would like to be able to have relationships between the two possibly, say like an item in the store could have posts

3. how do you handle namespaces if they do at all.... say i make an engine and put it on github, but your app uses some of the same names for models as mine did, would be nice if it was namespaced somehow to overcome that.


23. jason Mar 09, 2009 at 18:08

How does this relate to the Rails 3 plan of putting rails apps inside rails apps?

Will 2.3 Engines be in someway compatible with Rails 3?


24. m3talsmith Mar 23, 2009 at 19:08

Like Eric, my big question has to do with namespace collisions. I'm running some tests on that to see where it stands.


25. Paulie Mar 24, 2009 at 14:46

How do I get updates of my Engine to my users?
In other words, if I add a feature to my Engine, is there any mechanism for getting the new code to the apps that are using that Engine, or do I have to copy the code by hand to each app that is using it?


26. Paulie Mar 24, 2009 at 14:57

About Namespaces:

I've had that worry, too. I haven't tried this yet, but I'm thinking that I will put my code one folder deeper. In other words, if the name is my_engine, then my folder structure would look like this:

app
    controllers
        my_engine
            first_controller.rb
    helpers
        my_engine
            first_helper.rb

etc....


27. Patrick Espake Mar 27, 2009 at 10:23

I added the parameter --cvs-exclude with rsync to remove the directories from svn.

namespace :blogify do
  desc "Sync extra files from blogify plugin."
  task :sync do
    system "rsync -ruv --cvs-exclude vendor/plugins/blogify/db/migrate db"
    system "rsync -ruv --cvs-exclude vendor/plugins/blogify/public ."
  end
end


28. Korben Dallas Apr 02, 2009 at 04:18

Nobody have : A copy of ApplicationController has been removed from the module tree but is still active! ???

What are wrong ?!

Thanks for help me.

I found this but it's very old : http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/1155f9ab3a65d8e7/8c128eee5b943efd?pli=1


29. snowgiraffe Apr 25, 2009 at 14:06

I was wondering what the recommended approach is for building an engine where you anticipate that the main application will need to customize and possibly completely override a significant portion of the database schema, models, controllers and views. In other words, perhaps some of the MVC elements are more of a scaffold or skeleton for the main application. For example, suppose the existing application's models and tables collide with those of the engine and in some cases the model associations in the engine may need to be removed. Would it be possible/practical to include rake tasks to copy also the models (and views) up to the main application and undefine/disable them in the engine. Perhaps using a generator instead of a rake task would be preferred? For migrations, I imagine good documentation explaining how to edit the copied files if necessary would suffice.

Thanks for the railscast Ryan. Very cool.


30. samo Apr 30, 2009 at 09:38

@korben dallas: this may help

http://nerbie69.blogspot.com/2008/12/solved-applicationcontroller-has-been.html


31. James Adam May 01, 2009 at 05:32

snowgiraffe - if you need to make such significant changes to the models, etc in the plugin, you probably shouldn't build it as an engine in the first place; I don't know of any reasonable way to 'remove' an association from an existing class, for example. Perhaps there's a lowel level of abstraction that's more suited to the specific case you have in mind? Alternatively, you can provide modules/classes that your application can compose together, as required.


32. NOT SPAM Oct 12, 2009 at 19:54

Thanks for the screencast. I'm wondering if it's possible to move the engine out of the vendor/plugins directory and load it out of a path that is outside the primary app.

The reason is that I am running 4 different apps, that all run my engine. I only want to update my engine in one place, and have all 4 apps read it.

Is that possible?


33. burmajam Oct 16, 2009 at 03:13

I had problem as Korben Dallas had (A copy of ApplicationController has been removed from the module tree but is still active!).

Solution is unloadable as it is explained on http://strd6.com/?p=250.

In short, put 'unloadable' in your plugin controllers


34. freerealmscoins Jan 12, 2010 at 16:41

It is very good.I like to see it.I will try it.Thank you .Have a good time.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source