0

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?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Duncan Malashock
  • 776
  • 10
  • 32
  • 2
    Take a look at Jose Valim's [inherited_resources](https://github.com/josevalim/inherited_resources). It handles RESTful resources beautfiully, and supports nesting. On a side note, though, if sections or blocks can be uniquely addressed (do they have unique ids?) without specifying their parents, then you don't strictly need to have nested routes (unless you want them). – numbers1311407 Nov 03 '13 at 23:39
  • Thanks for the link; do you know if inherited_resources works with Rails 4.0? – Duncan Malashock Nov 04 '13 at 01:46
  • Yep it appears to have been updated for 4 – numbers1311407 Nov 04 '13 at 05:40
  • 1
    I didn't stress this properly before but if your resources are uniquely addressable without parents they *shouldn't* be nested. Typically any nesting of more than a single level is frowned upon. – numbers1311407 Nov 04 '13 at 05:45
  • Well they are uniquely addressable, but if they shouldn't be nested I think I'm back at square one. How would I construct the views and controllers to show only the Sections that belong to a particular Page, and pass in a Page's id to the section#create method without nesting? – Duncan Malashock Nov 04 '13 at 14:08

1 Answers1

0

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).

numbers1311407
  • 33,686
  • 9
  • 90
  • 92
  • Thanks for this– I'm stuck on the next part of this work as well: can you take a look at [this question](http://stackoverflow.com/questions/19795125/assign-relation-id-to-record-on-create-but-not-on-update) if you have a chance? – Duncan Malashock Nov 05 '13 at 17:37