Ashan Priyadarshana
Ashan Priyadarshana

Reputation: 3619

Set dynamic values when generating setter methods using attr_accessor in ruby

Is there a better way to set values to setter methods when they are made dynamically using attr_accessor method? I need this for setting values for them from another model in rails. I'm trying to do something like below.

Model_class.all.each do |mdl|
  attr_accessor(mdl.some_field)
end

Then I know that it creates a set of get and setter methods. What I want to do is, when these methods are get created, i want some value to be specified for setter method.Thanks in advance.

Upvotes: 0

Views: 577

Answers (2)

Jose Paez
Jose Paez

Reputation: 847

Here is another possible implementation for this:

  def attr_accessor(*args)
    args.each do |attribute|
      define_method(attribute.to_sym) { eval("@#{attribute}") }
      define_method((attribute.to_s + '=').to_sym) {|value| eval("@#{attribute} = value") }
    end
  end

Upvotes: 0

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

attr_accessor has no magic embedded. For each of params passed to it, it basically executes something like (the code is simplified and lacks necessary checks etc):

def attr_accessor(*vars)
  vars.each do |var|
    define_method var { instance_variable_get("@#{var}") }
    define_method "#{var}=" { |val| instance_variable_set("@#{var}", val) }
  end
end

That said, the attr_accessor :var1, :var2 DSL simply brings new 4 plain old good ruby methods. For what you are asking, one might take care about defining these methods (or some of them, or none,) themselves. For instance, for cumbersome setting with checks one might do:

attr_reader :variable # reader is reader, no magic

def variable=(val) do
  raise ArgumentError, "You must be kidding" if val.nil?
  @variable = val
end

The above is called as usual:

instance.variable = 42
#⇒ 42
instance.variable = nil
#⇒ ArgumentError: You must be kidding

Upvotes: 2

Related Questions