Reputation: 677
Problem appears when I want to remove element from paginated table in "ajaxized" way. My tasks controller calls its destroy method in response to [DELETE] /tasks/1234
, but at the end I want to redirect to index to get the list automatically refreshed.
Unfortunately, what redirect_to tasks_url
at this point does is [DELETE] /tasks
request.
Is there any way to force GET request instead of DELETE while redirecting from inside of destroy ?
Upvotes: 14
Views: 5530
Reputation: 239
Use redirect_to with status 303
def destroy
@task = Task.find(params[:id])
@task.destroy
redirect_to :action => :index, status: 303
end
redirect_to documentation says:
http://api.rubyonrails.org/classes/ActionController/Redirecting.html
If you are using XHR requests other than GET or POST and redirecting after the request then some browsers will follow the redirect using the original request method. This may lead to undesirable behavior such as a double DELETE. To work around this you can return a 303 See Other status code which will be followed using a GET request.
Upvotes: 23
Reputation: 677
Ok, so to sum up this question. The easiest way I found to fix the issue, is to mess a bit in routes.rb by adding: "tasks" => "tasks#index", :via => :get
and to use redirect_to tasks_url
(in my case) directly in destroy action in controller.
This will solve the problem with kaminari pager as well (which renders strange links in some cases).
Upvotes: 1
Reputation: 18080
You probably don't want to do a standard rails redirect when using ajax. This blog post has some good insight on the issue and solutions. Note this is from a similar question in January, answered by DGM
Upvotes: 0
Reputation: 1888
Why not to use :action param ?
def destroy
@task = Task.find(params[:id])
@task.destroy
redirect_to :action => :index
end
Upvotes: 0
Reputation: 709
I think you should rearrange your code on the client side:
destroy
action, await true or falseindex
at memorized page using ajax call.Upvotes: 0
Reputation: 53
Don't use redirect. Use render. Abstract the functionality to get the table data into a library module and then call that from both index as well as the delete methods, and then add then add the render call to the delete method so that the index view is what is sent back in response.
require 'myLibrary'
include myModule
def index
getTableData
end
def destroy
flash.now[:notice] = "Delete operation failed" unless Task.destroy(params[:id])
getTableData
render 'myController/index'
end
in lib/myLibrary
module myModule
def getTableData
# Table Foo here
end
end
Upvotes: 3