9

I have a button_to that I want to perform a PUT action (there is only one thing that can be updated about this resource - it will be updated as being 'acknowledged', so there are no other form fields associated with firing the action).

This is in my view (the controller is given explicitly because the button is on a view that belongs to another controller):

<%= button_to "Acknowledged", :controller => 'practice_sessions', :id => @practice_session.id, :method => :put %>

In my routes file, the resource has been declared as a restful resource:

  resources :practice_sessions

The controller for this resource has a create and an update action, and the button_to above calls the create action. I want it to call the update action.

This comes through the log right before the create action fires:

Started POST "/practice_sessions?id=21&method=put" for 127.0.0.1 at 2010-11-17 08:52:46 +0000
  Processing by PracticeSessionsController#create as HTML
  Parameters: {"authenticity_token"=>"1EW0IlI38d0f4wST5azrCEZVZPfih7i0UvCGSF7eqbc=", "id"=>"21", "method"=>"put"}
pakeha
  • 2,480
  • 3
  • 22
  • 24

3 Answers3

19

Your syntax is slightly off. button_to takes three arguments: the button title, an options hash, and an html_options hash. :method=>:put needs to go in html_options, while the route parameters need to go in options. So you can rewrite like so:

<%= button_to "Acknowledged", { :controller => 'practice_sessions',
  :id => @practice_session.id}, 
  :method => :put %>

When clicked the request should be handled by PracticeSessionsController#update

zetetic
  • 47,184
  • 10
  • 111
  • 119
  • Hi, thanks for this. I'm now getting 'No route matches "/practice_sessions"'. I think that's because it's PUTting to just /practice_sessions (as witnessed by the URL http://localhost:3000/practice_sessions?id=26) rather than /practice_sessions/26 in this case. I will keep playing with it, but any tips appreciated! – pakeha Nov 17 '10 at 00:12
  • What is the output of `rake routes`? – zetetic Nov 17 '10 at 00:19
  • Looks as expected. Here are the lines I imagine are of interest: practice_session PUT /practice_sessions/:id(.:format) {:action=>"update", :controller=>"practice_sessions"} practice_sessions POST /practice_sessions(.:format) {:action=>"create", :controller=>"practice_sessions"} – pakeha Nov 17 '10 at 06:22
  • I ended up solving the problem using named routes (see my answer), but I appreciate your input - it set me on the right track. – pakeha Nov 17 '10 at 06:37
3

In the end I decided to go with the more restful approach using named routes, which seems to work fine. I'm still not 100% sure why the other method wouldn't work, but I don't think it matters because this seems both a) more tidy and b) more conventional.

<%= button_to "Acknowledge", practice_session_path(@practice_session), :method => :put %>
pakeha
  • 2,480
  • 3
  • 22
  • 24
1

You might need to explicitly pass the :method => :put argument in the html_options hash - it might be getting globbed into the options hash.

Try this:

<%= button_to "Acknowledged", { :controller => 'practice_sessions', :id => @practice_session.id }, :method => :put %>

(Note the explicit braces around :controller and :id)

nfm
  • 19,689
  • 15
  • 60
  • 90
  • Hey, this wouldn't work for me (see my response to zetetic), but I ended up solving it using named routes (see my answer). Thanks for your input though - I should have noticed the separate arguments anyway. – pakeha Nov 17 '10 at 06:38