Ruby on Rails: Using a "complete_tasks_controller" for RESTful Rails
I'm having troubling completing a task the RESTful way. I have a "tasks" controller, and also a "complete_tasks" controller.
I have this in the complete_tasks_controller create action:
def create
@task = Task.find(params[:id])
@task.completed_at = Time.now
@tas开发者_JAVA百科k.save
end
I tried calling this:
<%=link_to "Complete task", new_task_complete_task_path(@task), :method => :post %>
..but I'm getting errors on that mentioning that "Only get, put, and delete requests are allowed."
Do you know what I'm doing wrong?
It would make more sense to move this into an action called complete in your controller:
def complete
@task = Task.find(params[:id])
@task.complete!
end
To access this action using RESTful routing you'll need to define a new member route like this in config/routes.rb:
map.resources :tasks, :member => { :complete => :put }
Adding :member => { :complete => :put }
to the end of any pre-existing map.resources :tasks
will do the trick also, you should only ever have one map.resources :tasks
line, unless it's nested. The routing guide explains this better than I ever could.
To get to it from the view:
link_to "Complete this task", complete_task_path(@task), :method => :put
The method complete!
would then be defined in your model like so:
def complete!
self.completed_at = Time.now
save!
end
The reason for this is that it puts the model logic where it belongs: in the model.
Each map.resources statement routes.rb creates a common RESTful routes for use with the specified resource. The appeal of REST is that is uses the request type and url to determine which action to take. Out of the four verbs associated with HTTP, each one has a specific use.
POST => Create
GET => Retrieve
PUT => Update
DELETE => Destroy
The reason you're getting an error about only get, put, and delete requests being allowed, is that you're using a post request. Essentially you're telling Rails you want to create a task with an id of one. However you cannot create an item that already exists. Which is why posts are not allowed. Instead you want to use put, because you're updating an existing record.
You can do it by changing post, to put in your link_to call.
<%=link_to "Complete task", new_task_complete_task_path(@task), :method => :put %>
Have a read through the routing guide and the resources documentation, it will help you understand the difference between HTTP requests, as well as provide some insight into how Rails handles those requests.
精彩评论