Normatron

Normatron is an attribute normalizer for Ruby On Rails ActiveRecord objects. With it you can convert attributes to the desired format before saving them in the database. This gem inhibits the work of having to override attributes or create a specific method to perform the normalizations.

Installation

Let the bundler install the gem by adding the following into your application gemfile:

gem 'normatron'

And then bundle it up:

$ bundle install

Or install it by yourself:

$ gem install normatron

The problem

Suppose you have a product model as the following:

# ./db/migrate/20120101010000_create_products.rb
class CreateProducts < ActiveRecord::Migration
  def change
    create_table :products do |t|
      t.string  :name
      t.decimal :price, :precision => 10, :scale => 2
    end
  end
end

# ./app/models/products.rb
class Product < ActiveRecord::Base
  attr_accessible :name, :price
end

And you want the ‘name’ attribute be uppercased before saving it into the database. The most usual approach to do it includes:

  • Override the ‘name’ setter and convert the value to an uppercased string.

  • Use the ‘before_validation’ callback to run a method or block doing the task.

Both ways are ilenegant, boring, error prone and very expensive. What led me to make this gem and offer a third way to solve the problem:

Usage

# ./app/models/products.rb
class Product < ActiveRecord::Base
  attr_accessible :name, :price

  normalize :name, :with => :upcase
end

$ rails console
> p = Product.create :name => "  memory   card    "
> p.name
=> "  MEMORY   CARD    "

You can also assign multiple attributes to the same filter:

normalize :name, :brand, :with => :capitalize

And multiple filters to an unique attribute:

normalize :email, :with => [:downcase, :squish]

Or mixing both:

normalize :name, :description, :with => [:upcase, :squish, :blank]

Filters

:upcase and :downcase

Change all character to upcase and downcase, respectively. Accented characters are affected too.

class User < ActiveRecord::Base
  attr_accessible :name

  normalize :name, :with => :upcase
end

$ rails console
> d = User.create :name => "Darth Vader"
> d.name
=> "DARTH VADER"
> j = User.create :name => " José    Negrão  "
> j.name
=> " JOSÉ    NEGRÃO  "

:capitalize

Capitalize the first character of the sequence. Accented characters are affected too.

class Player < ActiveRecord::Base
  attr_accessible :name, :race

  normalize :name, :race, :with => :capitalize
end

$ rails console
> a = Player.create :name => "ÉBANO PEREIRA", :race => " protoss"
> a.name
=> "Ébano pereira"
> a.race
=> " protoss"

:titlecase or :titleize

Capitalize the first character of each word. Accented characters are affected too.

class Player < ActiveRecord::Base
  attr_accessible :name, :race

  normalize :name, :race, :with => :titleize
end

$ rails console
> a = Player.create :name => "fernando rodrigues", :race => " zerg"
> a.name
=> "Fernando Rodrigues"
> a.race
=> " Zerg"

:strip, :lstrip and :rstrip

Remove trailing and/or leading spaces.

class Address < ActiveRecord::Base
  attr_accessible :city, :district, :street

  normalize :city, :with => :strip
  normalize :district, :with => :lstrip
  normalize :street, :with => :rstrip
end

$ rails console
> a = Address.create :city => " gotham ", :district => " red light ", :street => " no name "
> a.city
=> "gotham"
> a.district
=> "red light "
> a.street
=> " no name"

:squish

Remove trailing and leading spaces and then changing remaining consecutive whitespace groups into one space each.

class Product < ActiveRecord::Base
  attr_accessible :description

  normalize :description, :with => :squish
end

$ rails console
> p = Product.create :description => "   \t My   product is \n cheap!  !    !     "
> p.description
=> "My product is cheap!!!"

:blank

Convert a blank attribute into nil.

class Person < ActiveRecord::Base
  attr_accessible :gender, :name

  normalize :gender, :with => :blank
end

$ rails console
> p = Person.create :gender => "     ", :name => "  "
> p.gender
=> nil
> p.name
=> "  "

Contributing

  • Fork it, add your new features or bug fixes, make your tests and commit.

  • Report any bug or unexpected behavior.

  • Send me your feedback.

  • Pay me a beer. =]

Special Thanks

This gem was inspired on work of fnando called normalize_attributes. I just forked his gem and added some functionalities.
He has a lot of interesting gems on his repo, please take a look.

Licence

Copyright 2012 Fernando Rodrigues da Silva

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.