Plugin Authors: Toward a Better Future
Posted by wycats February 09, 2010 @ 11:05 AM
Some of the biggest changes in Rails 3 involve how Rails expects plugins to behave.
Dependencies
If your plugin has dependencies, make it a gem and have your users install it using the Gemfile. This will ensure that Bundler properly calculates the dependencies alongside any other dependencies the user’s app has.
If You Override Something, Require It
If you need to override ActionController, ActiveRecord or other Rails frameworks, require them first, then override. Instead of assuming that Rails will require your gem plugin at a “correct” time, assume that the user will require your plugin extremely early.
This gives you the opportunity to hook in earlier to the initialization process, but it also means that you should explicitly require the dependencies you need.
# in your_lib.rb
require "active_record"
require "your_lib/extensions"
ActiveRecord::Base.class_eval { include YourLib::Extensions }
Use a Railtie, But Only if You Need To
Even though you can expect your gem to load very early, you might still need to hook into a later part of the initialization process. If you do, inherit from Rails::Railties. Inside of a Railtie, you can declare a block that Rails should run when it runs Rakefiles, specify initialization blocks, add a subscriber to the notification system, and specify generators to load.
class TestingFu < Rails::Railtie
# This creates a config.my_plugin in the user's Application
railtie_name :testing_fu
rake_task do
load "testing_fu/tasks.rake"
end
# specify the default generators for test frameworks
config.generators.test_framework :testing_fu
# you can also specify :before or :after to ensure that
# your initializer block runs before or after another
# initializer block
initializer :setup_my_plugin do |app|
# in here, I have access to the user's application,
# which gives me access to app.config
end
end
Make sure to require any railties that you intend to extend. For instance, if you want to run an initializer before one defined in ActionController, require “action_controller/railtie”
That said, don’t use a Railtie if your code does not need to hook into any part of the Rails lifecycle. When possible, simply create a standard Ruby library, requiring the parts of Rails you need to override.
Engines
Engines in plugins (vendor/plugins) work as they did in Rails 2. In a gem, you’ll need to provide a Rails::Engine subclass:
# lib/my_engine.rb
module MyEngine
class Engine < ::Rails::Engine
engine_name :my_engine
end
end
Place your app directory next to the lib directory and Rails will pick it up. You can read the documentation for Railte, Engine, Plugin and Application, all in just one place, here: https://gist.github.com/af7e572c2dc973add221
Start a Conversation at railsplugins.org
In order to make this process easier, Engine Yard has put together railsplugins.org. If you’re a plugin author, please submit your plugins to that site. You can tell users whether or not you expect your plugins to work on Rails 3, whether or not your users can run them in threadsafe mode, and whether they run on JRuby.
Once you’ve put a plugin up there, users can say that they either agree that your plugin runs or disagree, with a comment about what is broken. You can reply to any such comments, and the user can change his mind if he just made a mistake. When you submit a new version, the site creates a whole new page, so comments about things not working on a previous version don’t clutter up the current version (users can still get at the old versions if they wish).
If we do this right, the Rails community will have a strong sense of what works on Rails 3 and what doesn’t. Have at it!

Now this is something to celebrate! I’ve been frustrated with trying to update plugins and gems w/ Rails, and having explicit dependencies sounds great!
I like that there are different ways of hooking into Rails depending on what your specific needs are.
And a plugin site that doesn’t suck, and ends up being pretty comprehensive fills in a key community need.
Getting excited about Rails 3!
Is there any difference in engines from 2.3? For example, are assets in the engine accessible from the main Rails application?
https://gist.github.com/e139fa787aa882c0aa9c is not working. What is the new URL? Thanks.
i pray the RoR 3.0 version will release as soon as possible @@
the RoR dev. team , +uuuuu
Do we really need yet another plugin site?
Certainly some collaboration could have happened to add compatibility info to http://agilewebdevelopment.com, and leverage the already-existing database of 1,500+ plugins.
ahe: I guess it’s https://gist.github.com/d646d17e2d7d034351b8
Agree with ben here. Whoever runs agilewebdevelopment could add a field for 3.0 compatibility?
Are Rails engines going to ever be on par with Merb slices?
When we’re at it – could we please drop those unecessary self.included/self.extended hacks? See http://pastie.org/821603
Testing Rails Engine plugins has changed with Rails 3, because the tricks for embedding a Rails app inside of the test folder inside the plugin and then loading the plugin into that app don’t work any more. I can’t find any examples of Rails Engine plugins with a Rails 3 app embedded for testing.
If anybody might be able to suggest an appropriate venue for me to ask questions about how to test a Rails Engine plugin for Rails 3, I would appreciate a pointer? Is this uncharted territory?
@apeiros I checked your pastie, and even suggested a better name for the ForActiveRecordBase class (I called it Activate). But boy, I am getting an “undefined method `acts_as_something’ for MyModel:Class”. May be cos I try it against ActiveResource instead of ActiveRecord? It doesn’t make sense.
@apeiros I found it! Just have to change “extend” for “include” in the last activation, and it works like a charm. I just updated the pastie.
I love this code, clean and beautiful, the rails guide should indeed be updated with it.
It still lacks a nice way to declare “alias_method :foo :bar”, but that has always been ugly anyway.
railsplugins.org is very helpful.
To the people who mentioned agilewebdevelopment.com, have you visited ruby-toolbox.com recently? I think the signal-to-noise ratio of the latter is far higher than the former.
agilewebdevelopment.com is very useful when looking for plug-ins that haven’t been updated since 2006.