views:

64

answers:

2

I'm fairly new to Ruby, and currently trying to implement an AJAX style commenting system.

When the user views a topic, all the current comments on that topic will be displayed.

The user can post a comment on the page of a topic and it should automatically display without having to refresh the page, along with any new comments that have been posted since the last comment currently displayed to the user.

The comments should also automatically refresh at a specified frequency.

I currently have the following code:

views/idea/view.html.erb

<%= periodically_call_remote(:update => "div_chat", :frequency => 1, :position => "top", :url => {:controller => "comment", :action => :test_view, :idea_id => @idea.id } ) %>
<div id="div_chat">
</div>

views/comment/test_view.html.erb

<% @comments.each do |c| %><div id="comment">
<%= c.comment %>
</div>
<% end %>

controllers/comment_controller.rb

class CommentController < ApplicationController 

before_filter :start_defs   

def add_comment
    @comment = Comment.new params[:comment]
    if @comment.save
        flash[:notice] = "Successfully commented."
    else
        flash[:notice] = "UnSuccessfully commented."
    end
end

def test_render
    @comments = Comment.find_all_by_idea_id(params[:idea_id], :order => "created_at DESC", :conditions => ["created_at > ?", @latest_time] )
    @latest = Comment.find(:first, :order => "created_at DESC")
    @latest_time = @latest.created_at
end

def start_defs
    @latest = Comment.find(:first, :order => "created_at ASC")
    @latest_time = @latest.created_at
end

end

The problem is that every time periodically_call_remote makes a call, it returns the entire list of comments for that topic. From what I can tell, the @latest_time gets constantly reset to the earliest created_at, rather than staying updated to the latest created_at after the comments have been retrieved.

I'm also not sure how I should directly refresh the comments when a comment is posted. Is it possible to force a call to periodically_call_remote on a successful save?

+1  A: 

You have to use remote form of rails.

Ref:- http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#M001650

When you submit the form you have to update the div. here no need to update whole div. For Ex:-

def add_comment#this method should called using ajax
    @comment = Comment.new params[:comment]
    render :update do|page|
      if @comment.save
        page.insert_html :top, partial=>"latest_comment", :object=>@comment
      else
        page << "alert('UnSuccessfully commented.')"
      end
    end
end

_latest_comment.hrml.erb

<%= @comment.comment %>
Salil
moved this comment to a new answer in order to format it.
Patrick Klingemann
A: 

no need for a partial in this case, you could simply do:

page.insert_html :top, 'div_chat', @comment.comment

Although, I do see some use of a partial if you were doing the following:

views/comment/test_view.html.erb

<% @comments.each do |c| %><div id="comment"><br />
<%= render 'latest_comment', :comment => comment %><br />
</div>
<% end %>

Then in page.insert_html you could render the latest_comment partial and you could ensure that all comments are rendered the same way.

Patrick Klingemann