Rails宝典之第六十五式: Stopping spam

这次要介绍的是使用 Akismet来预防垃圾comment
akismetor是作者写的一个插件: http://svn.railscasts.com/public/plugins/akismetor

使用akismetor需要如下几步

1,给comments表添加几个字段:
  add_column :comments, :user_ip,  :string
  add_column :comments, :user_agent, :string
  add_column :comments, :referrer, :string
  add_column :comments, :approved, :boolean, :default => false, :nul => false
  Comment.update_all("approved=1")


2,routes.rb:
  map.resources :comments, :collection => { :destroy_multiple => :delete },
                           :member => { :approve => :put, :reject => :put}


3,comment.rb:
before_create :check_for_spam

def request=(request)
  self.user_ip    = request.remote_ip
  self.user_agent = request.env['HTTP_USER_AGENT']
  self.referrer   = request.env['HTTP_REFERER']
end

def check_for_spam
  self.approved = !Akismetor.spam?(akismet_attributes)
  true
end

def akismet_attributes
  {
    :key                     => 'abc123',
    :blog                    => 'http://railscasts.com',
    :user_ip                 => user_ip,
    :user_agent              => user_agent,
    :comment_author          => name,
    :comment_author_email    => email,
    :comment_author_url      => site_url,
    :comment_content         => content
  }
end

def mark_as_spam!
  update_attribute(:approved, false)
  Akismetor.submit_spam(akismet_attributes)
end

def mark_as_ham!
  update_attribute(:approved, true)
  Akismetor.submit_ham(akismet_attributes)
end

def self.recent(limit, conditions = nil)
  find(:all, :limit => limit, :conditions => conditions, :order => 'created_at DESC')
end


4,comments_controller.rb:
def index
  @approved_comments = Comment.recent(20, :approved => true)
  @rejected_comments = Comment.recent(100, :approved => false ) if admin?
end

def create
  @comment = Comment.new(params[:comment])
  @comment.request = request
  if @comment.save
    if @comment.approved?
      flash[:notice] = "Thanks for the comment"
    else
      flash[:error] = "Unfortunately this comment is considered spam by Akismet. " +
                      "It will show up once it has been approved by the administrator."
    end
    redirect_to episode_path(@comment.episode_id)
  else
    render :action => 'new'
  end
end

def destroy_multiple
  Comment.destroy(params[:comment_ids])
  flash[:notice] = "Successfully destroyed comments."
  redirect_to comments_path
end

def approve
  @comment = Comment.find(parmas[:id])
  @comment.mark_as_ham!
  redirect_to comments_path
end

def reject
  @comment = Comment.find(params[:id])
  @comment.mark_as_spam!
  redirect_to comments_path
end


5,comments/index.rhtml:
<% title "Recent Comments" %>

<div class="content comments">
 <%= render :partial => 'comment', :collection => @approved_comments, :spacer_template => 'divider' %>
</div>

<% if admin? %>
<div class="content" id="rejected_comments">
  <% form_tag destroy_multiple_comments_path, :method => :delete do %>
    <h3>Rejected Comments</h3>
    <table>
      <% for comment in @rejected_comments %>
        <tr>
          <td><%= check_box_tag "comment_ids[]", comment.id, true %></td>
          <td><%= link_to h(comment.name), comment.site_url %></td>
          <td><%= h truncate(comment.content, 30) %></td>
          <td><%= link_to "not spam", approve_comment_path(comment), :confirm => 'Are you sure?', :method => :put %></td>
        </tr>
      <% end %>
    </table>
    <p><%= submit_tag "Destroy Checked" %></p>
  <% end %>
</div>
<% end %>

你可能感兴趣的:(SVN,Blog,Flash,UP,Rails)