I gotta have my orange juice.

Jesu, Juva

Rails pattern: trim spaces on input

with 3 comments

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.

Written by Scott Moonen

May 8, 2009 at 11:53 am

Posted in Patterns, Rails

Tagged with , , , ,

3 Responses

Subscribe to comments with RSS.

  1. Adding that last code to config/environment.rb didn’t work for me —  but putting that code in config/initializers/trimmers.rb *did* work.

    Not sure whether this is something in Rails 2.3.4, some plugin’s hand at work, or just dumbness on my part, though 🙂

    Thanks, though — this is just what I was looking for!

    TC

    October 19, 2009 at 6:25 am

  2. This pattern is not working for find_or_create_by_***:

    I am getting ConstraintException:column *** is not valid for the resources that are already in the database.

    I understand that this is because trimmed_field is using before_validation callback.

    Any idea how to fix this?

    Thanks,
    -Rakesh

    Rakesh Arora

    June 28, 2010 at 10:39 am

  3. There are some gems to automate this behavior. See for example https://github.com/holli/auto_strip_attributes

    Strip is the most commonly needed option. But also squishing “James Bond ” => “James Bond” is a good one when user copypastes lots of stuff to forms.

    Olli

    May 28, 2015 at 5:14 am


Leave a comment