Rails 3, Custom Actions, and HTML request methods

2019-07-16 14:24发布

问题:

I don't really understand the pro's and con's of using "post" vs "get" vs "put" requests, on custom controller actions, and whether to use links or forms/buttons.

So let's say I have a simple to-do list with tasks, and a tasks controller, and I want a "complete" action where I find a specific task in the db and update it's status attribute from "incomplete" to "complete."

def complete
  @task = Task.find(params[:id])
  if @task.update_attributes(:status => "complete")
    redirect_to tasks_url, :notice => "Completed!"
  else 
    redirect_to tasks_url, :error => "Whoops."
  end
end

What's the best practice way to define this route, which HTML request method should I use (post? put? get?), and should I use a plain link or a form? (and note: assume my user security model is all figured out with devise, and appropriate before filters, etc.)

And most of all, how would I articulate all this in a Rails 3 routes.rb file?

Note, the below code wasn't really working for me:

#routes.rb
resources :tasks do
   members do
     post 'complete'
   end
end

so currently I'm using this instead:

#routes.rb
match 'tasks/:id/complete', 'tasks#complete', :as => "complete_task"

#view
= link_to "Complete", complete_task_path(:id => @task.id)

But this triggers a get request, and I feel like it should be a "put" or a "post." Or should it be a link at all? Should it be a form with hidden fields?

回答1:

"link_to" method usually generates an anchor tag ie "<a></a>", ie a regular GET request

to do a POST request using link_to you should do the following

= link_to "Complete", complete_task_path(:id => @task.id), :method => :post

Remember if javascript is disabled in the browser, the above statement will fall back to a GET request instead of POST.