Creating nested resources in Rails can be a little bit tedious, particularly if you're using Rspec and its scaffolding. Updating the controller isn't really a problem, but making the specs pass involves a bit too much busy work. And then there are the views to take care of, and their specs, and don't forget the routing specs while you're at it.
Now you might suggest that make_resourceful and resource_controller offer a neat solution to this problem. Well, yes, sometimes. Often though, I find these super controllers tend to be a little too DRY for my tastes, at least on some projects. I'm usually happier starting with some generated code and hacking from there.
So what I'd really like to be able to do is scaffold out the nested resource and its specs. A quick look around Github turned up rspec_on_rails_nested_scaffold, a plugin which does just that. It is very nearly perfect for my needs, although I have forked it and updated the templates used for views and specs with those from the latest versions of Rails and Rspec respectively.
You can install the plugin like so:
script/plugin install git://github.com/phorsfall/rspec_on_rails_nested_scaffold.git
If you already have a Post resource you can create nested Comments like this:
script/generate rspec_nested_scaffold Comment --owner=Post post_id:integer body:text
This will generate a CommentsController which includes a before_filter to load the correct Post and has Active Record calls scoped accordingly. You also get views which include the correct links and form actions, along with updated controller, view and routing specs. Before you are finished however, there are a few small things you'll need to do by hand:
- Update
routes.rb. The generator will add an un-nestedmap.resourcesfor our nested resource. In our example, we'd remove this and add the following:map.resources :posts, :has_many => :comments - Create the Active Record associations in your models.
class Post < ActiveRecord::Base has_many :comments end class Comments < ActiveRecord::Base belongs_to :post end - If you didn't include a foreign key when you ran the generator, add one to the migration.
With that done, migrate the database and run the specs which should all pass. You now have an app you can go to work on and hopefully you've saved a bit of time along the way.
Thanks to Jeremy Friesen for putting the original plugin together.
