Question

I have three models: Page, Section, and Block. A Page has many Sections, and a Section has many Blocks. I'm trying to write it in such a way where the Page view has a form for creating new Sections, and the Section view has one for creating Blocks.

My problem is passing the page_id from the Page view to the section#create method; I'm not sure how it's done. In order to be RESTful, do I have to include the parent associations in the URL (i.e. a monster URL like www.mydomain.com/pages/1/sections/3/blocks/5) so I can get the id for a new query, and then do something like this?

def create
  @page = Page.find(params[:page_id])
  @section = @page.sections.build(section_params)

I've been reading this (http://ruby.railstutorial.org/), and it comes close to explaining a use case like mine, but I'm stuck. I'm sure there's a "Rails Way" of building CRUD routes where each resource is nested inside the next; can anyone enlighten me?

Was it helpful?

Solution

Take a look at Jose Valim's inherited_resources. It handles RESTful resources beautifully, and supports nesting.

However if your resources are uniquely addressable, you don't strictly need to nest them. The common advice recommends that you don't nest more than a single level deep. This is where :shallow routes came from, giving the ability to express nested relationships in routes.rb without creating giant URLs and named routes. Shallow routes also help to improve flexibility, allowing resources to be moved around/in/out of hierarchies without otherwise updating code.

How would I construct the views and controllers to show only the Sections that belong to a particular Page...?

Well as this particular example is only a single level deep, it still falls within the recommendations for a single level of nesting: /pages/1/sections. But for deeper nestings (or all if you kept everything top level), you would use the query string: e.g. /sections?page_id=1 or /sections/blocks?page_id=1.

...and pass in a Page's id to the section#create method without nesting?

This one is more straightforward. Put it in the form itself (as a hidden input, likely).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top