bernat farrero thinking

I enjoy building stuff that fits the needs of large groups of individuals. I specialized in doing so with limited resources, deep layers of uncertainty and great doses of ambition. I contribute to Internet startups that plan and rationalize their course of action.

 

I founded @itnig and @camaloon. While holding the helm of Camaloon I help other entrepreneurs at itnig to build products and services with strong technological and internet basis and deliberate vocation to differentiate.

jQuery and Rails 3: A mini tutorial

As most of Rails developers, recently I’ve been through a process of unlearning all concepts of older versions of Rails and learning again the new ones of 3. But hey! I must admit that so far it’s been more pleasure than pain as things only get simpler and more natural than they used to be!

Here I’d like to talk about how simple it has become to integrate unobtrusive jQuery to a Rails app. Let’s use as an example a system of comments. I’ll create a simple app to create YouTube like comments:

mostra1

Start typing in your teminal:

Then we have to include the jQuery library and the jQuery driver file and place it inside /public/javascripts/ (or grab the helpers generator of Code Officer and do it automatically if you wish).  Now remove the  javascript_include_tag :defaults in the layout and add the following includes:
/app/views/layouts/application.html.erb

 

Now let’s add some logic to our program.  We’ll start out with an index action that will get all the comments:
/app/controllers/comments_controller.rb

And the views for the index will look like this:
/app/views/comments/index.html.erb

Notice that the new attribute remote is all we need to worry about when creating a form that will submit with Ajax. Rails 3 works with HTML5 attributes, so it only adds the attribute data-remote=”true” to the form and that’s it, the jQuery driver will handle the rest.
We’ll create a partial for the comments:
/app/views/comments/_comment.html.erb

So now let’s add the fireworks! That is, the asynchronous creation and deletion of comments along with some trendy effects. We come back to the CommentsController and add the actions:
/app/controllers/comments_controller.rb

And we are done with the logic part! A few javascript lines will end the work:
/app/views/comments/create.js.erb

/app/views/comments/destroy.js.erb

Finish! That’s all the effort you need nowadays to a create a Web 2.0 fashionable feature such as this one. Of course, you need some styling with CSS, and you would need tons of more things in the real world (such as antispam, authentication, something to comment about…) but that’s the part I chose to talk about today!

I pushed myCommentsApp to Github in case you want to have a closer look (or download the zip version).

You might be interested in checking out my script for letting user in-place edit your application contents.

 

66 Comments

  1. Jordi

    4 years ago

    Wow that code looks familiar to me!

    That’s a very useful code, I think every comment system should be like this by now, people is getting used to it and feels weird the get the old school redirect.

    Also, this code is perfectly compatible with Rails 2, except in rails 2 you don’t need the “jquery rails driver” but the jrails plugin, and instead of using form_for with the :remote => true you should use remote_form_for.

    PS: The textarea for submitting comments (in your blog, no the example app) has way too big font size! I have like 4 words per line XD

    PS2: I like the new imperative to attract people to comment…

  2. Bernat

    4 years ago

    Of course it is familiar to you dude, I coded it first for our joint project semantic.cat (http://github.com/bernat/semantic) and copy&pasted after to my blog, so as to be useful to someone else (which may not be the case).

    Indeed, the way you code Ajax actions now and before hasn’t changed that much apparently, though it has in the inside. Taking profit of HTML5 attributes now there’s no need to add blocks of javascript code mixed with markup, you redefine everything separately in your “driver”. In fact, you can capture more actions defining new remote handlers almost painlessly, creating as “data-” attributes as you wish.

    You’re right about the font-size being too big, I’ll have it change… someday!

  3. [...] equivalent for Prototype helper plugin yet so that would be an issue like in my case. Based on this jQuery and Rails 3 tutorial, using the jQuery UJS driver looks very [...]

  4. Cristian

    4 years ago

    Thanks, it has been really useful for me.

  5. Juba

    4 years ago

    Wow, thanks ! This tutorial was exactly what I was looking for. Now I think I even understand the use of .js.erb files !

  6. v

    4 years ago

    tes

  7. Cipe

    4 years ago

    Hi dude! That’s great

  8. Blake

    4 years ago

    Cheers for the tutorial… helped me get a few cool things working :)

  9. Flunder

    4 years ago

    Thanks alot! This was very handy, thanks for putting it up!

  10. chrismealy

    4 years ago

    Thanks for the tutorial. It was exactly what I needed. Even better, your code on github worked with zero trouble.

  11. [...] equivalent for Prototype helper plugin yet so that would be an issue like in my case. Based on this jQuery and Rails 3 tutorial, using the jQuery UJS driver looks very [...]

  12. Fabio

    4 years ago

    Thanks for the article, very useful…

  13. Moshe

    4 years ago

    I found an issue with this method of using jquery – escape_javascript removes javascript from the partial. What happens if you need javascript in the partial? for example for autocomplete?

  14. Puneet Pandey

    4 years ago

    Thanks for sharing this quick tutorial… its very helpful.

    Regards
    Puneet

  15. bernat

    4 years ago

    Hey Moshe, excuse me I did not see your reply. This was just the simplest of all possible ways to do it but of course you don’t have to escape javascript, once you’ve got the @comment you can display it the way you like and use all the power of jQuery. If you give me a specific example I can try to help.

  16. Sunny

    4 years ago

    Hi thanks for the guide, helped me a lot. One thing I don’t understand is how the flash message is shown
    “flash.delete(:notice)” this part especially seems strange because of the delete word when we’re trying to show it.

  17. bernat

    4 years ago

    Hello Sunny,
    when you display a flash notice you want to do both things at a time: One is to actually display it and the other is to clear it out so it won’t show up at the next request. With flash.delete[:notice] we do both.

  18. zegal

    4 years ago

    nice, thanks.

  19. Thimo

    4 years ago

    Hi, thanks for that very nice tutorial :) But I have a
    problem ;) I have exectly the same code and it works all fine
    expect of the all the things in the create.js.erb :-/ There is no
    highlighting or notice… I use Mozilla Firefox 3.6.11 I got the
    following failure in the failure console of firefox: Fehler:
    uncaught exception: [Exception... "Cannot modify properties of a
    WrappedNative" nsresult: "0x80570034
    (NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN)" location: "JS frame ::
    chrome://global/content/bindings/autocomplete.xml ::
    onxblpopuphiding :: line 825" data: no] Is there any other way to
    get your nice result without that exception?

  20. coda

    4 years ago

    yaaaayyy! awesome

  21. Doug

    4 years ago

    This is great, awesome, woo yeah!

  22. Lyadon

    4 years ago

    something!!!

  23. fernando

    4 years ago

    uahuuuuu !!!

  24. jordan

    4 years ago

    awesome

  25. Javix

    4 years ago

    Nice tutorial. Some improvements are needed nevertheless:
    - add validations for a comment(no empty comment body or comment name)
    - flash notice need to be fade out after deleting a comment, for example like that:

    $(‘.flash.notice’).fadeOut(); #in destroy.js.erb

  26. Jakko

    4 years ago

    Great stuff!

  27. Pancho

    4 years ago

    Fantastic tutorial! It’s been really useful :)

  28. Alejandro

    4 years ago

    Hi,
    i have some prblems. all code works fine, but, if i have a “format.html” on respod_to and in template a button_to with :remote => true, the format.js dont respond, always shows the format.html unless i comment that line.

    how can i fix that? maybe i doing something wrong.

    thanks.

  29. bernat

    4 years ago

    I’m not sure I understand your problem. If you add a :remote => true in your template AND you have the jQuery driver for Rails Helpers added in your layout, you should be able to catch a JS request by adding the format.js line in the respond_to block. If it goes to format.html, as you say, it’s because you are doing a regular synchronous request. Probably not have the jquery.rails.js. If you do a JS (AJAX) request you will only notice what happens by looking at your server console.

  30. Pizzicatto

    4 years ago

    THanx, man.. good mini-tutorial! :)

  31. josh

    4 years ago

    good one

  32. Ryan

    3 years ago

    Thank you. Very informative.

  33. Markus

    3 years ago

    > As most of Rails developers, recently I’ve been through a
    > process of unlearning all concepts of older versions of Rails
    > and learning again the new ones of 3.

    Is there a good starting point to learn the concepts? I tried to find something, but not sure yet.

    I have also tried to run your application. But it doesn’t work. Once I have submitted the form it stops with an error message. However, the record is stored in the database. Do I have to install or copy any js libaries before running the application?

  34. Markus

    3 years ago

    I just tried again with the zip-file. After extracting, I did:

    bundle install
    rake db:migrate
    rails s

    In the browser I add a comment and pressed the submit button. Nothing happened in the browser and in the console I got the following error message.

    http://bit.ly/dYHJg7

    Any ideas?

  35. Josh

    3 years ago

    Wow this is very nice!

  36. Bijesh

    3 years ago

    This is nice tutorial. Facing problem in one case. After AJAX request, I want to redirect_to different page instead of updating RESPONSE in any div, how can we do this ?

  37. zlorfi

    3 years ago

    Hi,

    it seems your
    $(“#new_comment”)[0].reset();
    doesn’t reset the comment form, nor does
    $(“#new_comment”).get(0).reset();
    seem to help :/
    The rest seems to work.

  38. paul

    3 years ago

    Thanks for writing this blog entry, everything worked great. I’m unclear about the following statement:

    render :partial => @comments, :locals => { :list => true }

    I cannot seem to find out where the locals :list is being referenced. Where should I be looking? I poked around the ‘render’ documentation and also div_for and contact_tag_for and was unable to understand how that symbol is being used.

    Thanks again!

  39. Tenshi

    3 years ago

    Nice!

  40. Kleber

    3 years ago

    Hi paul,

    As I understand, rails will look for a file called _comments under your comments folder in your views, and in this file (_comments.html.erb) you should be able to access the comment variable as a list.

    So, this way, you don’t have to do an “for” to generate it.

    Hope it helps anyway.

  41. Luiz

    3 years ago

    Thanks for the nice tutorial

  42. vignesh

    3 years ago

    Thanks for this tutorial….It helped me a lot in developing my own rails app :)

  43. Mack

    3 years ago

    This is awesome tutorial!

  44. Chip

    3 years ago

    Fantastic. Very well done — I searched high and low for something as clear and straightforward as this. I was able to quickly move forward on a project I’ve been working on, and had hit a roadblock. Thank you!

  45. Sathish

    3 years ago

    I like it your post because i implemented that on my project but i try to add email for gravatar photo will appear in the comment .. it says error how to do it..
    Thanks in advances

  46. Rachid

    3 years ago

    Well done! but why did you not put -J in the first rails calls, that would spare you deleting files ;-)

  47. najob

    3 years ago

    Hi, love the tutorial and the commenting system is very nice.

  48. Mamoun

    3 years ago

    I love you man thanks a bunch from a junior rails developer :)

  49. Carlo

    3 years ago

    Man there is an error:
    Missing template comments/create with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html], :locale=>[:en, :en]} in view paths “/home/carlo/Desktop/myCommentApp/app/views”

  50. Dan

    3 years ago

    Hi, I like your tutorial. Short and sweet. I have a question. I am trying to create a http link that will invoke a form submit via ajax. How can I do it?

  51. rubylicious

    3 years ago

    Nicely done sir!

  52. fearless fool

    3 years ago

    This was a great help — thanks. BTW, a slightly cleaner way to include jQuery in your app:

    [1] add the line gem 'jquery-rails' to your Gemfile
    [2] execute bundle install on the command line
    [3] execute rails generate jquery:install on the command line

    That will remove the unused prototype code, install jQuery and jquery_ujs. Now you can leave the original javascript_include_tag :defaults in views/layouts/application.html.erb.

  53. fearless fool

    3 years ago

    @bernat: I liked your example so much that I made a fork of myCommentsApp and tweaked it to use the latest Rails with postgresql with README instructions on how to deploy it on Heroku. See github link above.

  54. edmond

    3 years ago

    thanks a lot.

  55. Cory Logan

    3 years ago

    I really appreciate the simplicity of the tutorial. I still have not yet digested all of it, but it’s in a wonderful bite sized chunk. Thanks!

  56. Guru Prasad

    3 years ago

    Nice tutorial.
    Thanks a lot :)

    ~gurufrequent

  57. Pat Shaughnesy

    3 years ago

    Thanks a lot, Bernat – this was very helpful for me too… nice job writing: just enough info but not more.

  58. Rick

    3 years ago

    Thanks for the tutorial.

    I’m really new to Ruby on Rails, but I was curious. How could the Web page “invoke” the functionality of a form submission, in order to activate Javascript/JQuery code?

    Perhaps this is a fundamental axiom with this framework, but I’m very green to RoR.

    I currently have Ruby 1.8.7 and Rails 3.0.9. I’ve also installed the “jquery-rails” gem, whereby my application uses JQuery for its Javascript library, rather than Prototype. How would I update information, dynamically, “after” a page loads?

    I’m trying to fetch info from another site for an area of a page, after it’s loaded. I don’t want the user to wait for the entire page to load, because the page is waiting for one DIV’s content to render.

    Would anyone have any feedback on that? I’ve thought of doing the work you outline in this tutorial, but I don’t want to have to force a user to click on a form link on my page, in order to do that.

    Any feedback would be GREATLY appreciated. Thanks in advance RoR community!!

  59. Mark William

    3 years ago

    Thank you so much for the tutorial.
    i liked it very much.
    Thank you for sharing.

  60. saurabh udaniya

    3 years ago

    this is the best lesson of ajax thanks a lot

  61. Anto

    2 years ago

    Hey man, pretty cool. One caveat though: on the form_for, you forgot an = sign to display the form :)
    should go
    true do |f| %>

    great work though! cheers!

  62. Anto

    2 years ago

    Don’t know what happened. here’s the line!

    true do |f| %>

  63. Alexis

    2 years ago

    Great tutorial, but instead of fadeOut, why not removing the element?

  64. [...] could have a look at this short tutorial: http://blog.bernatfarrero.com/jquery-and-rails-3-mini-tutorial/ Tagged: jquery, questions, ruby-on-rails, ruby-on-rails-3 /* * * CONFIGURATION [...]

  65. harshit

    2 years ago

    Thanks for tutorial..

  66. Ramprabhu

    2 years ago

    This is really awesome.
    I have one question though. what is your rails version ? Because I am using rails 3.2.8 version.Here deleting user comments functionality is not working. While clicking on delete link, it just redirect to the “show” action in controller instead of going to destroy action. I think there is some problem while firing with ajax. It would be appreciate, please help me out.

LEAVE A COMMENT