2010/01/09

Ajax を使ってコメントを挿入

Ajax をつかって、記事(article)にコメント(comment)を挿入するほうほう。よく使うわりにはいつもはまってしまうので備忘録。(カフェトークでは、レッスンにメモを追加するところにつかってます)

article.rb
class Article < ActiveRecord::Base
  belongs_to :user
  has_many :comments
  after_update :save_comments
  
  def new_comment_attributes=(comment_attributes)
    comment_attributes.each do |attributes|
      comments.build(attributes) if attributes[:content].length > 0
    end
  end
  
  # ここでは使ってない
  def existing_comment_attributes=(comment_attributes)
    comments.reject(&:new_record?).each do |comment|
      attributes = comment_attributes[comment.id.to_s]
      if attributes
        comment.attributes = attributes
      else
        comments.delete(comment)
      end
    end
  end
  
  def save_comments
    comments.each do |comment|
      comment.save(false)
    end
  end  
  
  # 特定のユーザのみに表示するためのメソッド
  def user_comments
    self.comments.find(:all, :conditions => {:display_user => true})
  end
end

comment.rb
class Comment < ActiveRecord::Base
  belongs_to :article 
end
views/articles/show.html.erb
<div id="comments">
 <% for comment in @article.pro_comments %>
  <%= render :partial => 'comment_item', :locals => {:comment_item => comment} %>
 <% end %>
</div>
<%= link_to_function "コメント追加" do |page|
      page.insert_html :bottom, :add_comment, :partial => 'comment' , :object => comment.new
<% end%>
<div id="add_comment"></div>

views/pro/articles/_comment_item.html.erb
<div class="comment" id="comment_<%= comment_item.id %>">
 <%= comment_item.content%>
</div>

views/articles/_comment.html.erb
<div class="add_comment" >
<% @comment = Comment.new %>
<% form_remote_for ([:comment, @article]), 
  :url => add_comment_article_path(@article), :html => { :method => 'put' } do |f| %>
   <%= f.text_area :content %>
  <%= f.submit "追加"  %>
<% end %>
</div>

add_comment.rjs
if params[:comment]
  @comment= comment.new(params[:comment])
  if @comment.save
    comment_item_id = "comment_" + @comment.id.to_s
    page.insert_html :bottom, "comments", :partial => "comment_item", :object => @comment
    page[comment_item_id].visual_effect :highlight, :duration => 0.5, :startcolor => "#66CCFF"
    page.replace_html "add_comment", ""
  else
    @comment.errors.each{|attr,msg| page.alert("#{attr} - #{msg}")}
  end      
end

routes.rb
map.resources :articles, :member => {:add_comment => :put}

0 件のコメント: