Deleting a record using ajax
The rails scaffold produces following code for deleting a record.
<%= link_to 'Destroy', user, :confirm => 'Are you sure?',
:method => :delete %>
I want to delete the record using Ajax so that the whole page is not reloaded after every single delete. Since I use jQuery, I would add following line to my Gemfile.
gem 'jquery-rails', '>= 0.2.6'
And then I would run
rails generate jquery:install
Now I am all set. Howeer if I click "Destroy" then record is getting destroyed but the browser version is not being removed. Let's fix that.
First thing I need to do is to respond_to "ajax" requets in destroy action. After changing the controller the method looks like this.
def destroy
@user = User.find(params[:id])
@user.destroy
respond_to do |format|
format.html { redirect_to(users_url) }
format.js { render :text => "alert('user has been deleted')" }
end
end
And in application.js I would add just one line.
$('a[data-method="delete"]').live('ajax:success', function(){});
Then index.html.erb will look like this.
<%= link_to 'Destroy', user, :confirm => 'Are you sure?',
:method => :delete,
:remote => true
%>
Now when you delete a user, the user record will be deleted using ajax and an alert will come up with the message user has been deleted.
Deleting record using JSON data-type
JSON is the currency of communication in JavaScript world. So let's say that I want ajax request to respond with the name of the user who is being deleted and then I would construct the message on the client. Changed code would look like this.
def destroy
@user = User.find(params[:id])
@user.destroy
respond_to do |format|
format.html { redirect_to(users_url) }
format.js { render :json => {:name => 'John'} }
end
end
And in application.js I would have following lines.
$('a[data-method="delete"]').live('ajax:success',
function(data, textStatus, jqXHR){
alert(data.name + ' has been deleted');
});
Then index.html.erb will look like this.
<%= link_to 'Destroy', user, :confirm => 'Are you sure?',
:method => :delete,
:remote => true,
'data-type' => 'json' %>
Now when you delete a user, you will get the message undefined has been deleted. What's going wrong.
Notice that the function that is invoked when ajax:success callbacks happen has three parameters. The order of the parameters matches with the order of the paramers in jQuery ajax call for success.
In order to solve the problem you need to know how rails.js invokes the callbacks. The relevant code in rails.js is
element.trigger('ajax:success', [data, status, xhr]);
When trigger is used then the very first parameter passed is the event object. The function that is invoked will get the event object as the first parameter and then rest of the parameters are passed. This is just the way trigger works in jQuery.
Based on that information the JavaScript code should be changed to following in application.js .
$('a[data-method="delete"]').live('ajax:success',
function(e, data, textStatus, jqXHR){
alert(data.name + ' has been deleted');
}
);
You can follow this issue to see a real world example of this topic.