Loading more comments using AJAX in Rails

ajax, ruby-on-rails

Solution

Your problem is that you're mixing concepts. You get your choice of using `link_to_remote` with the :update option, or using RJS. Not both.

When you use `link_to_remote` with the :update option your view expects to receive a chunk of html which will replace the inner html of the DOM element matching the id provided to :update. In your case, this is the comments div.

Your format .js section is rendering the rjs template because you haven't told it to do anything else and it's generating javascript, which the link_to_remote treats as html uses it to replace the comments div.

You have two solutions:

Use `link_to_remote` with `:update`

Your view doesn't change, and your rjs file goes unused. To implement this fix replace the foramt.js line in your controller with this:

 format.js { render :partial => 'comments', :collection => @comments}

Use RJS

In this solution, your controller doesn't change. all you have to do is remove the `, :update =>'comments'` from your `link_to_remote` call.

Problem

I am currently implementing a blog-like site using Ruby on Rails. Each "Post" has some comments. Currently I only have the latest 5 comments load, but I want to implement a hyperlink that would load the rest of the comments. Unfortunately with my current implementation, all I get is a bunch of junk spit out. Before ``` Comments Posted 7 minutes ago New Posted 1 day ago Comment 3 Posted 1 day ago Comment 2 Posted 1 day ago Comment 1 Posted 1 day ago This is a new comment View more comments ``` After Click 'View more comments' ``` Comments try { Element.insert("comments", { bottom: " \n \n Posted 1 day ago\n \n Comment 2\n \n " }); Element.insert("comments", { bottom: " \n \n Posted 1 day ago\n \n Comment 3\n \n " }); Element.insert("comments", { bottom: " \n \n Posted less than a minute ago\n \n New\n \n " }); Element.hide("morecomments"); } catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.insert(\"comments\", { bottom: \" \\n \\n Posted 1 day ago\\n \\n Comment 2\\n \\n \" });\nElement.insert(\"comments\", { bottom: \" \\n \\n Posted 1 day ago\\n \\n Comment 3\\n \\n \" });\nElement.insert(\"comments\", { bottom: \" \\n \\n Posted less than a minute ago\\n \\n New\\n \\n \" });\nElement.hide(\"morecomments\");'); throw e } ``` The post's show.html.erb has: ``` <div id="morecomments"> <%= link_to_remote "View more comments", :url=>{:action=>'morecomments',:post_id=>@post.id},:update=>'comments' %> </div> ``` In my post controller I have ``` def morecomments @post = Post.find(params[:post_id]) @comments = @post.comments.values_at(Range.new(5, @post.comments.size-1)) respond_to do |format| format.html {redirect_to @post.comments} format.js end end ``` And finally my morecomments.js.rjs: ``` @comments.each do |p| page.insert_html :bottom, :comments, :partial => p end page.hide 'morecomments' ``` I'm really new to Rails, and I don't really know about all of the meta magic rails is doing in the background. Any help would be awesome. Thank you!

Original source