How to perform Controller.destroy action asynchronously in rails?

北城以北 提交于 2019-12-08 02:54:09

问题


I can easily delete the entries of post synchronously in rails application by following code:

views

<% @post.each do |post| %>
 <tr>
   <td colspan="3"><%= link_to 'Destroy', post, :method => :delete, :confirm => 'Are you sure?', :class => 'btn btn-mini btn-danger' %></td>
 </tr>
<% end %>

Controller class

def destroy
 @post = Post.find(params[:id])
 @post.destroy
 respond_to do |format|
   format.html redirect_to(posts_url) }
   format.xml  { head :ok }
 end
end

This works fine. How make this destroy process async. So, that I will not required to add route or refresh the page.

Edit

Adding more explanation

Task is to make destroy method async. So that the client will not wait for the response and destroy method will run in background async. Also the destroy method has no guaranteed completion time.

Another example could be: I have to delete multiple post at a time.


回答1:


For making Async request you need Ajax and basic javascript to remove the code of <td>.

First change your views code to :

<% @post.each do |post| %>
<tr>
  <td colspan="3"><%= link_to 'Destroy', post, :method=> :delete, id: post.id, :class => 'btn btn-mini btn-danger', data: { confirm: 'Are you Sure?', remote: true } %> </td>
</tr>
<% end %>

Above code says that it will call the destroy method of PostController class. Now you need to make some changes in destroy method of controller class

def destroy
 @post = Post.find(params[:id])
 @post.destroy
 respond_to do |format|
   format.js 
   format.html { redirect_to(posts_url) }
 end
end

Above code is pretty understandable, except why we use respond_to. In rails we can render the data in two ways:

  1. Javascript

  2. HTML

we will use javascript to render the code because it's a easy way to remove the <td> tag with the help of ID.

Now we need a js file to render the response of destroy method. To do this add destroy.js.erb in the same folder of your views.

Add this following code in destroy.js.erb:

 var element = document.getElementById("<%= @post.id %>");
 element.parentNode.parentNode.remove();

You are done! I will recommend you to read : http://www.gotealeaf.com/blog/the-detailed-guide-on-how-ajax-works-with-ruby-on-rails




回答2:


Try remote: true option,

<%= link_to 'Destroy', post, :method => :delete, remote: true, :confirm => 'Are you sure?', :class => 'btn btn-mini btn-danger' %>

def destroy
  @post = Post.find(params[:id])
  @post.destroy

  # Just Guessing you have @posts to refresh and `posts_template` using it.
  @posts = Post.all 

  respond_to do |format|
    format.html redirect_to(posts_url) }
    format.xml  { head :ok }
    format.js { render 'posts.js.erb' }
  end
end

posts.js.erb

$('some_element').replaceWith('<%=j render 'posts_template' %>');

Please change as you need. I am just guessing.



来源:https://stackoverflow.com/questions/31129766/how-to-perform-controller-destroy-action-asynchronously-in-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!