Oops! Rails already has something better than Engines

posted: May 1st, 2008 · by: Sven

in: · tagged as: , , ·  4 comments »

… because it already has Engines for Rails 2.0.

You can file this in the category of “Doh!” and “Things: obvious, but missed” … at least that applies to me. Did you notice it?

I’ve just recognized that with todays Engines and Rails 2.0’s config.plugin_paths you can do exactly what John W. Long envisioned and called for one and a half year ago.

To check that out I’ve reassemled an application that I’m currently working on and that uses Engines to modularize things and added this line to config/environment.rb:


config.plugin_paths << 'vendor/engines'

Now I have a working application with a directory layout like this:


vendor/
  engines/
    adva_blog/
      app/
        controllers/
        helpers/
        models/
        views/
      db/
        migrate/
      init.rb
      routes.rb
    adva_cms/
      ...
    adva_comments/
      ...
    adva_wiki/
      ...
  plugins/
    acts_as_list/
    acts_as_paranoid/
    ...
    will_paginate/

At the same time, the app/ directory is almost empty, because this application is meant as a base or platform for custom applications. Obviously one could move the vendor/engines/ folder somewhere else. Perhaps to apps/ below the app/ directory?.

I totally love this!

But, yeah. Of course this is not exactly the same like what John was talking about. He spoke of first-class sub-apps, i.e. something that’s conceptually on the same level as the Rails “app” itself. With Engines those apps are just plugins.

“Just plugins” in Rails 2.0 means that they are actually very powerful. But there are also some traps with unexpected Depenendcies and class reloading issues that plugins in Rails do not live on the same level as the app. They seem to be meant as framework-level extensions, not application-level extensions.

If Rails would at some point compensate for that, probably by inventing the concept of a dedicated “application-level plugin” that behaves exactly the same way as the application itself does (i.e. reloads in dev mode), … then John’s vision finally would have become real.

Until then, though, I’m super happy to be able to store higher-level Engines separate from lower-level plugins :)

Application-level plugins?

The point is that when it comes to, e.g., using ActiveRecord Observers Rails Dependencies produces errors that can be pretty hard to track when models from plugins are involved. There are other several scenarios like this.

My solution to these issues so far is to put the following line into my plugin’s init.rb file:


Dependencies.load_once_paths -= Dependencies.load_once_paths.select{|path| \
  path =~ %r(^#{File.dirname(__FILE__)}) }  

I haven’t understood Dependencies well enough yet though to be sure if that’s the best way to do have everything in a plugin be reloaded seemlessly with every request in dev mode. But so far it works quite well.

If you happen to know a better solution please let me know!

Maybe it would be a nice idea to wrap that sucker above into a method on Engines::Plugin. Something like: reloadable! and call that from the init.rb file instead.

Leave a comment

4 Comments

  1. court3nay said May 1st, 2008 at 11:50 PM  

    we’re doing some of this in http://github.com/courtenay/tentacle/

  2. Sven said May 2nd, 2008 at 10:19 AM  

    Hi Court3nay!

    Yeah, Rick send me that URL the other day but the project was empty at that point. That stuff looks very interesting! From the first look tentacle seems to have a different focus from this project. I’ll have a closer look asap … maybe we can join forces somehow at some point? Or at least make sure that we can share some engines, probably.

  3. James said May 4th, 2008 at 12:59 AM  

    I tried to post comments to John’s article when he wrote it originally, but they never made it onto his site.

    I’d really love to get some tests that demonstrate the reloading Dependencies problems. Got any ideas? :)

  4. Sven said May 11th, 2008 at 05:55 PM  

    Hi James!

    I’m bad at remembering these things and making definite statements offhand. Your question motivates me to sit down and check out some scenarios. I’ll get back to you as soon as I have something.

    Thanks :)

Leave a comment

Name required
E-Mail and Website optional

If you can read this, you don't use a typical webbrowser that plays nice with CSS.
Please do not fill in anything here!

Hint: Markdown will be applied to your comment. If you post any code, be sure to escape underscores (like so: \_) if you do not want them to be converted to an <em>phasis.

artweb design
Sven Fuchs
Grünberger Str. 65
10245 Berlin, Germany


http://www.artweb-design.de

Fon +49 (30) 47 98 69 96
Fax +49 (30) 47 98 69 97