1

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?

iamlemur
  • 151
  • 2
  • 8

2 Answers2

3

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
  • 47,184
  • 10
  • 111
  • 119
  • 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 Oct 31 '10 at 02:53
  • 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 Oct 31 '10 at 03:42
1

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
  • 2,069
  • 17
  • 25
  • Not quite. Should be `:id => 2`, not `:story_id => 2` – zetetic Oct 30 '10 at 20:45
  • That makes sense, thanks. But I'm afraid I'm missing something far more remedial. How do I access this from the view? – iamlemur Oct 31 '10 at 02:52
  • @iamlemur - possibly a bit late to the party, but hopefully helpful for others - to access the result of `find_stack` from the view, also assign an instance variable - such as `@stack = Stack.find(params[:stack_id])`. You can then access `@stack` from the view. – Steve Folly Mar 22 '17 at 06:30