Archive for May 2009
Rails pattern: trim spaces on input
Problem: Your Rails application accepts user input for a number of models. For many or most of these fields, leading and trailing spaces are a significant inconvenience — they cause problems for your validators (email address, phone number, etc.) and they cause normalization and uniqueness problems in your database.
Solution: Just as the Rails ActiveRecord class uses methods like belongs_to and validates_format_of to define model relationships and behaviors, create a new class method to express trimming behavior. There are a number of ways to do this; I will present one possibility that I have used in my own code. I created a file lib/trimmer.rb with the following contents:
module Trimmer # Make a class method available to define space-trimming behavior. def self.included base base.extend(ClassMethods) end module ClassMethods # Register a before-validation handler for the given fields to # trim leading and trailing spaces. def trimmed_fields *field_list before_validation do |model| field_list.each do |n| model[n] = model[n].strip if model[n].respond_to?('strip') end end end end end
Then I write the following in my models:
require 'trimmer' class MyModel < ActiveRecord::Base include Trimmer . . . trimmed_fields :first_name, :last_name, :email, :phone . . . end
While this makes the behavior available to particular models explicitly, you may prefer to make this behavior available to all of your models implicitly. In that case, you can extend the ActiveRecord::Base class behavior by adding the following to config/environment.rb:
require 'trimmer' class ActiveRecord::Base include Trimmer end
If you do this, the trimmed_fields class method will be available to all of your models.