Defend your Rails from spam with Akismet
July 24, 2009 - 2 Comments - ruby rails spam tools akismet
When I decided that I would roll code.isdangero.us as a custom-made blog in Rails, I thought of it as a fun, easy project. After all, blogs are simple, and the simplicity allows for plenty of room for attention to detail in making the code as tight as possible, similar to the way a haiku allows a poet to express his skill in language through the power of the simply-stated.
Of course, every project looks easy from a distance, because unforeseen problems are just that: unforeseen. It had been a while since I’d blogged, and therefore I had all but forgotten about the long war of blog software against the endless networks of compromised Windows machines turned into Viagra-pitching zombies, comparable in number to the mighty armies of ancient Persia.
Enter Akismet
Just as the 300 men under the command of King Leonidas of Sparta held back Persia’s onslaught by fighting in the shade, the forces of good in this war have gathered together their disparate forces into a collective known as Akismet.
Akismet is an API which tracks spam and ham submissions from participating blogs all over the world, building its knowledge of what spam looks like versus comments from good-natured, decent folks who aren’t trying to sell the latest antidepressant through your blog. It allows a blog to ask if a comment looks like spam before publishing it. It also allows the owner of that blog to tell Akismet when a comment is marked as spam or ham, thus giving back to Akismet’s intelligence with human analysis.
Integrating Akismet into your Rails app
I used a simple, one-file Ruby library for the base-level HTTP interaction with Akismet’s API. Download it, and then drop it into your lib directory in your Rails project.
You will want to have your comments begin storing the IP address, user agent, and HTTP referrer of the client posting the comment, as well as its “spam” status. This is achieved with a simple migration:
script/generate migration AddSpamInfoToDiscussions ip_address:string user_agent:string referer:string spam:boolean
You will probably want to edit this migration to add a default value to the spam column.
When your controller creates a Discussion record for an incoming comment, you can add this data like so:
Now let’s add a callback to our model which will ask Akismet if the comment looks like spam, and if so, mark it as such before saving it.
Let’s add a couple more methods for marking an existing Discussion as spam or ham:
And corresponding controller actions:
Hook up your routes (you’re RESTful, right?), and that’s it, you’re done! Unless of course you want a nice admin UI for checking comments and marking them as spam or ham, but I will leave that part up to you. All the functionality is in place, so have fun building that beautiful UI.
I hope someone finds this helpful. Fuck off, spammers!

Arya Asemanfar said:
Just kidding!
I ran into a similar problem and decided to just completely discard comments that Akismet thought are spam.
Akismet is pretty cool but when I was signing up, it required me to sign up for wordpress to get an API key, is that still true? I also remember there being an alternative to akismet, forgot the name though.