views:

28

answers:

2

I've got two objects (@stacks and @stories) with has_many relationships (through @anthologies). Stories can be viewed individually (/stories/1/) or as a collection in a Stack (/stacks/1/stories/1/).

map.resources :stories
map.resources :anthologies
map.resources :stacks, :has_many => :stories do |stack|
  stack.resources :stories
end  

I've got this basic frame working I'm trying to identify the when a story is being rendered as part of a stack so that I can build some navigation between stories. I figure the easiest way to do this is to check the URL for the primary controller, but 1) I don't know how to do this, and 2) it seems very un-Railsy, like there should be a more direct way.

Still getting my head around some of the basics of Rails here -- any recommendations on how to achieve the desired functionality?

+1  A: 

if you are accessing the child resource then the params will include the parent resource by default.

For example "/stacks/1/stories/2/" will have a params structure like this:

{:action => 'show', :controller => 'stories', :stack_id => 1, :id => 2 }

If you want to find the nested resource in the controller just look for the presence of the parent_id in the params hash e.g.:

before_filter :find_stack

protected
def find_stack
  if params[:stack_id]
     Stack.find(params[:stack_id])
  end
end
heavysixer
Not quite. Should be `:id => 2`, not `:story_id => 2`
zetetic
That makes sense, thanks. But I'm afraid I'm missing something far more remedial. How do I access this from the view?
iamlemur
+1  A: 

You've defined both nested and non-nested routes for :stories. When your StoriesController receives a request with these parameters:

/stacks/1/stories # nested form

or with these

/stories # non-nested form

The route will map to {:controller => :stories, :action => :index }. In the nested form, the params hash will include :stack_id => 1. In the non-nested form, it won't.

zetetic
Thanks. I get this in concept, but I'm missing how I actually check if stack_id is set from the view? I'm still groping around rails, and I can't seem to find the right way to access the variable to check if it's set and return the value. Any pointers?
iamlemur
That depends on how you handle the controller action. Typically you would set an instance variable, like `@stack = Stack.find(params[:stack_id)`. You can conditionally set this, as in the `before_filter` example. In the view, you can test for the existence of the variable using `defined?`, e.g., <% if defined? @stack %>
zetetic