I want to write a Rails plugin, which adds a controller to a rails app. It seems like it should be easy, plugins are fairly flexible after all. After a couple of experiments, I concluded that you need at least the following defined in your plugin:
1 2 3 4 5 |
|
1 2 |
|
But there’s still a serious problem. It only works on the first request. After much mucking around in routing.rb, I’ve found out why. It turns out that when a request is finished, dispatcher.rb clears out all the controllers, so that routing.rb will reload them on the next request (only in development mode). The problem is, that the controller in the plugin doesn’t live in one of the “trusted” paths1, so can’t be reloaded. So, on the second and subsequent requests, you get a routing failure.
There’s a quick and easy way around this.
1 2 3 4 5 6 7 |
|
But that means that you have to restart the web server each time that you change your plugin, which certainly isn’t ideal. At this point, I started thinking about monkey-patching how the reloading works, but a gag reflex caused me to take a step back and think differently.
One minor tip: running rake rails:freeze:gems
makes it much easier to dig into the rails source code. Mostly because it all becomes immediately accessible from within textmate’s “Go To File” command.
Looking around the web, I can’t find much information about controllers in plugins. One answer appears to be the rails engines plugins. But it appears to be more heavyweight than I’d like.
However, nuby on rails mentions an interesting alternative.
You can’t directly write a controller plugin, but you can write a generator that copies a controller to your app/controllers directory.
The more that I think about this, the more it makes sense to me. It ensures that magic URL namespaces don’t just “appear” in your application. It also provides a point for overriding aspects of the actions I wish to provide. In addition to all that, it’s just plain better separated so easier to test.
And I haven’t even begin to think about how the views are going to work…
1 app/
, lib/
and components/
according to safe_load_paths.