Easily add custom getter and setter filters for attributes on ActiveRecord objects. These can be useful if you wish to scrub data before it hits your datastore and/or provide uniformity when reading.


For Ruby 1.9.0 and greater. Tested with Rails 3.1+ using ActiveRecord. It should work with any ORM that provides a hash syntax for accessing attributes in Models (please let me know if you have success/failures with other ORMs).


Add the requirement to your Gemfile

gem "in_format"

That's it if using ActiveRecord. If using a different ORM you will need to extend InFormat on the models, add an initializer or shoehorn it in some other way.


Invoke in_format, phone_format or ssn_format in your Model for attributes you wish to process.


The in_format method is the most general and accepts a getter and/or a setter.

Under the hood these create setters/getters and process the value through the supplied Proc/lambda and set/read the value using the hash syntax (self[:attribute_name]).

There is an use_accessor option which will override getter/setter methods matching the attribute. This can be useful if you want to combine in_format with attr_accessor or gems like attr_encrypted (just be sure that the overridden methods exist before using in_format).

You can access the original getter by passing true to the new one (assuming you supplied a getter).

class MyModel < ActiveRecord::Base
  in_format :name, setter: lambda {|v| v.upcase }, getter: lambda {|v| "Mrs. #{v}"}

  attr_accessor :some_attribute
  in_format :some_attribute, use_accessor: true, setter: -> v { "#{v}s"}, getter: -> v { "3 {v}"}

  m = "shirley") #=> "SHIRLEY" #=> "Mrs. SHIRLEY"
  m.some_attribute = "beer"
  m.some_attribute(true) #=> "beers"
  m.some_attribute #=> "3 beers"

This example is contrived and a little dangerous, nil) #=> splode!, but you can do a lot with getters/setters.


phone_format uses in_format with some pre-defined getters and setters.

class MyModel < ActiveRecord::Base
  phone_format :phone
  phone_format :phone_without_getter, getter: false

  m = "(213) 222-2222", phone_without_getter: "(213) 222-2222") #=> "2132222222" #=> "222-222-2222"
  m.phone_without_getter #=> "2132222222"

You can supply your own getter or setter like in_format if the defaults don't match your needs or you can pass a getter or setter with false to exclude it.


ssn_format works much like phone_format, also accepts custom getters/setters.

class MyModel < ActiveRecord::Base
  ssn_format :ssn

or with attr_encrypted

class MyModel < ActiveRecord::Base
  attr_encrypted :ssn # defined before call to ssn_format
  ssn_format :ssn, use_accessor: true

  m = "123 45 6789") #=> "123456789" #=> "123-45-6789"


If you have getters/setters you would like to re-use across many attributes or classes I would stick em all in a (well-tested) module and keep an eye out for edge cases. You can also use in_format as the base for your own custom methods like phone_format, etc.

module MyFormatters
  CAPS = -> v { |v| v ? v.to_s.capitalize : "Generic Dog Name" }
  NO_CATS = lambda do |v|
    if v =~ /cat/
      v.gsub("cat", "")

class MyModel < ActiveRecord::Base
  in_format :dog_name, setter: MyFormatters::NO_CATS, getter: MyFormatters::CAPS


Currently this is written specifically for ActiveRecord but I hope to make it compatible with more ORMs. In the meantime you can use the alias option and it should work with any ruby class.