Monday, January 14, 2013

Learning How to Use Rails and Ajax Together

Sometimes we need to make post requests to controller actions to perform logic that we need to return back to the views. This can easily be handled with the help of jQuery and a little understanding of how Rails handles request.
This may not be the best scenario for this to be applied, but I am just giving a simple example of this use.
Let's say for example we have this code on the index page listing all the blogs:
<a href="#" id="save"> Save Changes </a>

<section id="main">
  <% @blogs.each do |blog| %>
    <section class="post">
      <%= check_box_tag :featured, "featured", blog.featured  %>
      <%= label_tag :featured %>

      <h2> <%= blog.title %> </h2>
      <p> <%= blog.body %> </p>
    </section>
  <% end %>
</section>
By clicking the "save" link we want to update all the checked blogs to be featured in the backend and re-render the list ordered by their featured status.
Let's start off by setting up our javascript and get started writing this functionality.
<script>
  $(function() {
    $("#save").on('click', function(e) {
      e.preventDefault();
      // will do the fancy stuff later
    });
  });
</script>
We start off when the dom is loaded and ready to be acted upon. We then add an event listener to the link with an ID of "save" and prevent the default behavior from happening when that link is clicked. We will handle this ourself with a post request to our backend.
Next we need to compose the data we will be sending to the server. We will be doing this by creating an array of objects that contain the ID of the object, and whether it is featured or not. Once we have this array of objects we'll send this information to the server to apply the changes.
<a href="#" id="save"> Save Changes </a>

<section id="main">
  <% @blogs.each do |blog| %>
    <section class="post" data-blog-id="<%= blog.id %>">
      <%= check_box_tag :featured, "featured", blog.featured  %>
      <%= label_tag :featured %>

      <h2> <%= blog.title %> </h2>
      <p> <%= blog.body %> </p>
    </section>
  <% end %>
</section>

<script>
  $(function() {
    $("#save").on('click', function(e) {
      e.preventDefault();
      var blog_information = [];

      $('section.post').each(function(i, post){
        var post_id   = $(this).data('blog-id'),
            featured  = $(this).find("input[name='featured']").is(':checked');

        blog_information.push({ post_id: post_id, featured: featured })

        // will send information to the server
      });

    });
  });
</script>
Here we add a data attribute of blog-id to the post in order to access the objects ID within our jQuery code. Then in our javascript we loop over each section with a class of post and contruct an object with the blog ID and its respected featured boolean flag. Once we have the object we push that into an array that we will send to server to be processed.
<script>
  $(function() {
    $("#save").on('click', function(e) {
      e.preventDefault();
      var blog_information = [];

      $('section.post').each(function(i, post){
        var post_id   = $(this).data('blog-id'),
            featured  = $(this).find("input[name='featured']").is(':checked');

        blog_information.push({ post_id: post_id, featured: featured })

        $.post("/filter_featured", { blog_information: blog_information }, function(data) {
          // stuff will happen once we handle the data in the server
        });
      });

    });
  });
</script>

routes

PostRenderTutorial::Application.routes.draw do
  match "/filter_featured", to: "blogs#filter_featured"
end

controller

class BlogsController < ApplicationController
  def filter_featured
  end 
end
As you can see here, we are making a POST request to a route that we define to direct to the filter_featured action in the blogs controller. In here we are going to update the records and re-render the layout and return the updated HTML. So lets get to it.
class BlogsController < ApplicationController

  ...  

  def filter_featured
    @blogs = Blog.by_featured

    params[:blog_information].each do |blog_info|
      blog_info = blog_info[1]
      blog = Blog.find blog_info["post_id"].to_i
      blog.update_attribute(:featured, blog_info["featured"]) unless blog.featured == blog_info["featured"]
    end

    render "featured_blogs", layout: false 
  end 

  ... 

end
This method is pretty basic. We first loop over each of the paramaters that were sent from our javascript POST request, and then we update the blog's featured column if it has changed. Then render "featured blogs" that will handle the new HTML.

featured_blogs.html.erb

<% @blogs.each do |blog| %>
  <section class="post" data-blog-id="<%= blog.id %>">
    <%= check_box_tag :featured, "featured", blog.featured  %>
    <%= label_tag :featured %>

    <h2> <%= blog.title %> </h2>
    <p> <%= blog.body %> </p>
  </section>
<% end %>

Blog.rb

class Blog < ActiveRecord::Base
  attr_accessible :featured
  scope :by_featured, order("featured = ?", true)
end
Here we are essentially recreating the structure we had previously. This is the HTML that will be returned from the POST request in our initial code. Let's get back there and finish this off.
<script>
  $(function() {
    $("#save").on('click', function(e) {
      e.preventDefault();
      var blog_information = [];

      $('section.post').each(function(i, post){
        var post_id   = $(this).data('post-id'),
            featured  = $(this).find("input[name='featured']").is(':checked');

        blog_information.push({ post_id: post_id, featured: featured })

        $.post("/filter_featured", { blog_information: blog_information }, function(data) {
          $("#main").html(data);
        });
      });

    });
  });
</script>
That's all it takes. One more line and we have replaced the HTML with the newly updated statuses of the blog posts. Again, this could be handled a much cleaner way, but I am simply trying to demonstrate how jQuery can be used and to hopefully give people a better understanding of how to construct your own custom actions.

This article was written by Garrett Heinlen a Senior Rails Developer at Software Allies.

16 comments:

  1. If i wrong to input that code and then i fail to use rails and ajax, so can i have a problem or some bugs too?

    ReplyDelete
  2. It’s an remarkable article in support of all the webb users;
    they will take advantage from it I am sure. poker dewa | agen bola online Can you also check

    ReplyDelete
  3. cabling contractors dc Banner Technologies has a professional team of VoIP experts, IT technicians, and other highly skilled employees, and can assist in deciding which VoIP service is best suited for each company. The company's experience with cabling services and telecommunications is an asset, ensuring efficiency for any business.

    ReplyDelete
  4. One more advantage is that you can get detailed information about the usage of the software, its specifications, its advantage and disadvantage and for what purposes this software is most suited. click here

    ReplyDelete
  5. Life becomes more interesting and wonderful when you share your memorable moments with friends and family through unique photographs. You can create your own unique style impressed with image editing software. And after hours of work stress you can also

    whatsapp messenger
    baixar whatsapp
    whatsapp plus
    download whatsapp
    whatsapp baixar


    ReplyDelete
  6. You need to have time to take care of the active. It in fact was a amusement account it. Look advanced to far added agreeable from you.

    entrar hotmail agora , hotmail entrar, entrar hotmail , entrar no hotmail

    ReplyDelete
  7. You need to have time to take care of the active. It in fact was a amusement account it. Look advanced to far added agreeable from you.

    entrar hotmail agora , hotmail entrar, entrar hotmail , entrar no hotmail

    ReplyDelete
  8. You need to have time to take care of the active. It in fact was a amusement account it. Look advanced to far added agreeable from you.

    banana kong download , banana kong , baixar banana kong , download banana kong

    ReplyDelete
  9. Mostly people have all the same things when they are writing academic task or any other writing, especially light music most people like during the writing.

    subway surf , baixar subway surf, subway surf download , download subway surf

    ReplyDelete
  10. Life becomes more interesting and wonderful when you share your memorable moments with friends and family through unique photographs. You can create your own unique style impressed with image editing software. And after hours of work stress you can also

    Square Quick
    Square Quick
    Square Quick
    Square Quick
    Square Quick

    ReplyDelete
  11. Mostly people have all the same things when they are writing academic task or any other writing, especially light music most people like during the writing.
    dream league soccer download , dream league soccer apk , download dream league soccer , dream league soccer

    ReplyDelete
  12. You need to have time to take care of the active. It in fact was a amusement account it. Look advanced to far added agreeable from you.
    Hotmail
    Hotmail Iniciar Sesión
    Iniciar Sesión
    Iniciar Sesión Hotmail
    Iniciar Sesión
    Iniciar Sesión Hotmail

    ReplyDelete
  13. I really thank you for the valuable info on this great subject and look forward to more great posts. Thanks a lot for enjoying this beauty article with me.

    geometry dash pc, geometry Dash, geometry dash lite, geometry dash play, geometry dash online

    ReplyDelete
  14. Mostly people have all the same things when they are writing academic task or any other writing, especially light music most people like during the writing.
    facebook iniciar sesión , facebook, iniciar sesion , iniciar sesion facebook

    ReplyDelete
  15. Your blog posts are more interesting and impressive. I think there are many people like and visit it regularly, including me.I actually appreciate your own position and I will be sure to come back here.
    hotmail login l login hotmai l hotmail log in l hotmail sign in l hotmail sign up

    ReplyDelete
  16. Nice! thank you so much! Thank you for sharing. Your blog posts are more interesting and impressive. I think there are many people like and visit it regularly, including me.I actually appreciate your own position and I will be sure to come back here.
    facebook baixar l baixar facebook l baixar facebook gratis l facebook movel l facebook movel baixar

    ReplyDelete