ActiveRecord and programmatically working with attributes.
Saturday, February 17, 2007 at 06:30PM
Wayne Robinson in programming, ruby on rails

Ruby on Rails is great. Partially because of all the ORM stuff and partially because Ruby is infitely extendable and overrideable (yes, I just made that word up).

On my current project, I have a lot of extended attributes in models that modify other attributes or even other models entirely. So, when I create new objects and assign their attributes, I would prefer the mass assignments to go through these custom mutators.

Now in Ruby, this is relatively simple. When you want to call a method within an object programmatically, you can use the #send method:

    str = "Hello world!"
    puts str.send(:size)

    Displays: 12

However, when you are performing property setting, you have to do some manipulation to the attribute name first before you can assign a value to it. For example, the code for sending the values of a hash to the corresponding mutator methods in a Person object would be the following:

    hash = {
        :first_name => "Wayne",
        :last_name => "Robinson",
        :date_of_birth => "1982-02-15"
    }

    hash.each do | key, value |
      person.send("#{key}=", value)
    end

As you can see, there is a little bit of repetition there if you have to use that in more than one place. So, I've DRYed this code into the following ActiveRecord extension. Just pop this active_record_getters_and_setters.rb file in your lib/ directory and require it in your environment.rb file with:

    require 'active_record_getters_and_setters.rb' 

You will now have three extra methods accessible to you in all your ActiveRecord objects.

ActiveRecord::Base#set(attribute, value)
    Assigns value to the mutator (setter) for attribute.

ActiveRecord::Base#get(attribute)
    Gets the value from the accessor (getter) for attribute.

ActiveRecord::Base#set_attributes(attribute_hash)
   Does an ActiveRecord::Base#set for each key/value pair in attribute_hash.

Article originally appeared on Wayne Robinson's Blog (http://wayne-robinson.com/).
See website for complete article licensing information.