views:

763

answers:

1

A model named 'book' with attributes 'name' and 'id' is given. How can i use this collection select to call the show-action of a certain book? The one code mentioned below returns the following error message:

Couldn't find Book with ID=book_id

<% form_tag(book_path(:book_id)), :method => :get  do %>
  <p>
  <%= label(:book, :id, 'Show Book:') %>
    <%= @books = Books.find(:all, :order => :name)
      collection_select(:book, :id, @books, :id, :name) 
  %> 
  </p>
  <p>
  <%= submit_tag 'Go' %>
  </p>
<% end %>
+1  A: 

book_path is generated once only, for the form tag itself. It won't be updated whenever your selection changes.

When you submit that form, it's going to request the following URL:

/books/book_id?book[id]=5

Since your book_path thinks book_id is the ID number you wanted, it tries to look that up. You could do what you want you by changing the code in your controller from:

@book = Book.find(params[:id])

to:

@book = Book.find(params[:book][:id])

But it kind of smells bad so be warned.

Luke
Thanks a lot Luke. Any suggestion for a non-smelly solution? I just need a drop-down menu to select a certain book to show...
Javier
Because the "smelly-solution" would break default-calls to the show action using book_path(id), wouldn't it?
Javier
You could try to select the ID from either field, like so:@book = Book.find(params[:book].try(:[],:id) || params[:id])That would work, but the smell still persists because you're not technically supposed to use RESTful routes like that. Balance 'getting it done' with 'following conventions'.
Luke