Skip to content

Ruby Class with Mass assignable attributes

September 23, 2010

Well, this is very weired again, but it seems ruby class does not allow me to have mass assignable attributes as you could do with the ActiveRecord models using attr_accessible or attr_accessor.

Its very painful to have too many getters and setters in the class and to assign them manually when you create an object of that class or to have constructor which has those hundreds of params.

So, how do we achieve that. Well there are two ways.

1. The hacky way:

class Woo
attr_accessor :f_name, :l_name
def initialize(params)
#instance_eval &block
params.each do |key, value|
eval("self.#{key}= '#{value}'") if self.respond_to? "#{key}="
end
end
end
woo = Woo.new(:f_name => "first_name", :l_name => "last_name")

What we are doing here is that we are trying to assign these instance variables in an eval loop. So the constructor to the method just takes all your parameter hash and then tries to see if your class responds to that method setter (which it should as you have defined the att_accessors for those instance variable already), and then assigns them the corresponding value from the hash.

2. The cleaner way, but which hides what you have inside as attributes

require 'ostruct'
Class woo < OpenStruct
end
woo = Woo.new(:f_name => "first_name", :l_name => "last_name", any_no_of_craps...)

OpenStruct is nothing but another container like a hash in ruby which just gets better when it comes to serialization of these objects (which in my own case is a need)

Hope that helps a bit to someone!!

One Comment leave one →
  1. bob permalink
    October 27, 2010 6:18 am

    instead of
    eval(“self.#{key}= ‘#{value}’”)
    you could write
    self.send(“#{key}=”.to_sym, value)

Leave a comment