Comment Spam

I first started noticing the comment spam about two weeks ago. Unfortunatly, I was too busy to create a perment solution and decided to flush the database. However, after doing this about five times, I realized that they weren’t going to quit. Apparently, the spammers had a lot of “gold” to unload. The comments were pretty funny actually. They claimed my site “was as good as gold” and linked to somesite (never actually clicked the link) to where you could presumable (get conned into) buying gold.

The change, although in retrospect should have been trivial to implement, gave me quite the headache. It had to do with the fact that I was not doing any error checking with regards to the AJAX comment posts. Since I was allowing for anonymous posts, I just populated in any missing information with a set of defaults. I wasn’t even checking for an empty comment!? So in essence, the comment posting was a quick hack job and in dire need of some TLC.

So once I added the simple_captcha and validates_presence_of magick into the comment model everything was pretty much golden. To get started, first add the following to your comment model:

validates_presence_of :comment
apply_simple_captcha

And then comment controller, change your validation check to the CAPTCHA valid_with_captcha? method:

@comment.valid_with_captcha?

Now everything seemed to be in place, but there was one little problem. If I tried to post most than one comment, it would only work for the first one. After stracthing my head for way to long I realized that I wasn’t updating the CAPTCHA image. Since the page is updated via AJAX and not refreshed, the CAPTCHA image was stale. A few minutes later and some more AJAX magick and the comment system with CAPTCHA verifcation is in working order.

The entire comment method looks like that (I am using the acts_as_commentable plugin):

def new
    @commentable = @commentable_class.find(params[:id])
    @comment = Comment.new(params[:comment])
    @comment.user = current_user if logged_in?
    @comment.title = 'Untitled'  if @comment.title.blank?
    @comment.name = 'Anonymous'  if @comment.name.blank? && !logged_in?
    @comment.ip_address = request.remote_ip

    respond_to do |format|
      if logged_in? || @comment.valid_with_captcha?
        @commentable.comments << @comment
        format.js do
          render :update do |page|
            page.insert_html :bottom, 'comments',
              :partial => 'comments/comment',
              :locals => { :index => @commentable.comments.size, :comment => @comment }
            page.visual_effect :highlight, 'comments', :duration => 3
            page.replace_html "commentbox", :partial => 'posts/comment_box',
                                            :locals => { :commentable => @commentable }
          end
        end
      else
        format.js do
          render :update do |page|
            page.replace_html "commentbox", :partial => 'posts/comment_box',
                                            :locals => { :commentable => @commentable }
          end
        end
      end
    end
  end

The comment_box partial just decides whether or not to load the anonymous form. All the magic happens in the anonymous form partial:

<% remote_form_for :comment, :url=>{:controller=>'comments', :action=>'new', :id=> commentable.id, :commentable_type => commentable.class } do |f| %>
  <dl>
    <dt><label for="title_entry">Message title <strong>(optional)</strong>:</label></dt>
    <dd><%= f.text_field 'title' %></dd>
    <dt><label for="title_entry">Name<strong>(optional)</strong>:</label></dt>
    <dd><%= f.text_field 'name' %></dd>
    <dt><label for="title_entry">Email<strong>(optional)</strong>:</label></dt>
    <dd><%= f.text_field 'email' %></dd>
    <dt><label for="comment_entry">Your comment</label> <strong>(<a href="http://textism.com/tools/textile/" title="Textile">Textile</a> permitted; HTML renders as source code)</strong>:</dt>
    <dd><%= f.text_area 'comment', :rows=>8, :cols=>60 %><dd>
    <%= show_simple_captcha(:object=>"comment") %>
  </dl>
  <%= submit_tag 'Add Comment'%>
<% end %>

Let me know what you think and comment away!

Discuss

Was it good for you, too? Join the discussion »


About the Author

Thumb_diet_coke Michael Petnuch is a graduate math student who enjoys walking on his hands, drinking diet coke, solving math problems, and being silly!