Announcing validates_blacklist – a Ruby Gem for Rails


New rails gem: validates_blacklist

Last week, I had a client issue – somebody was spamming a very important web form on their site.  This form kicks off a very intricate membership process, and even integrates with SalesForce.  Luckily in this instance, the spambots were using a consistent set of e-mail addresses that we could block.  But how?  Validations seem like the obvious choice, but who wants to gunk up the model with what is essentially config data?

Or maybe you want to block new users from selecting a username that makes them sound like an admin.  You might want to disallow usernames like admin, root, staff, or variations on your own name.  Again, this would gunk up the model.

Enter validates_blacklist, a simple ActiveRecord mixin that makes this process easy.  Setup blacklist values for any model attribute.  These values can be strings, regular expressions, numbers, number ranges, and almost any evaluation you can think of.

For the Impatient

You can watch this screencast where I create a rails app from scratch, install the gem, and use it. This will give you a good idea of what it’s all about, although reading further will give you all the details.

Installation

Stick this little line in your environment.rb:

config.gem 'bellmyer-validates_blacklist', :lib => 'validates_blacklist',
  :source => 'http://gems.github.com'

Then, for fun, run these two rake tasks:

rake gems:install
rake gems:unpack

Run this command to create blacklist files for all your models in the config/blacklists/ folder:

script/generate blacklists

Don’t worry, it won’t overwrite your existing blacklist files, only create the ones you’re missing. This means you can run it after every new model is added, no worries.

Now, call this in your models:

validates_blacklist

And populate the yaml files using the example below to guide you. Have fun!

Example

As an example, we’ll imagine a high school girl named Heather. Although she has mad Ruby skillz (perhaps BECAUSE) she’s a snob. All her potential friends must submit applications for friendship via her Rails website. She uses validates_blacklist to weed out the “undesireables”.

# config/blacklists/user_blacklist.yml
email:
 - greasy_pete@yahoo.com # We kissed once when we were 5. Get over it already.
 - /@aol.com$/           # Like, yeah right, AOL is for losers!

age:
 - <14    # Junior high?  Need not apply.  - >25    # Gross, you perv!

parents_salary:
 - 50_000..150_000    # Middle class is so passe.
# app/models/user.rb
class User < ActiveRecord::Base
  validates_blacklist
end

Explanation

Basically, under each attribute (email, age, parents_salary, etc) you can list as many blacklisted values as you like. They can be a simple strings:

greasy_pete@aol.com

or regular expressions, if you wrap them in forward slashes:

/aol.com$/

or numbers (not very exciting):

5

or ranges of numbers:

5..15

or any other conditionals you can think of:

!= 'sadness'
=~ /happiness/
!~ /sad/
> 12
< 99

The only limits are your imagination, and my forethought. You can even specify
the error message that is generated:

email:
 - [stinky_pete@aol.com, cannot be greasy pete from biology]

age:
 - ['> 25', cannot be a pervert]

parents_salary
 - ['50_000..150_000', cannot be middle class]

Otherwise, the user will receive a generic message like:

Email is not allowed

Of course, you can change that for an entire model with the mixin call:

validates_blacklist :message => 'is not valid'

or per attribute:

validates_blacklist :message => "is not valid',
  :attributes => { :email => 'has been banned', :age => 'is not allowed' }

For the record, I think even a 21 year old hitting on high school girls is a pervert, but I’m trying to approach this thing from Heather’s point of view.

About these ads

Tags: , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: