在Ruby中使用attr_accessor生成setter方法时设置动态值

cygmwpex  于 2022-10-15  发布在  Ruby
关注(0)|答案(2)|浏览(113)

当setter方法是使用attr_accessor方法动态生成的时,有没有更好的方法来设置值?我需要它来从Rails中的另一个模型为它们设置值。我正在试着做一些类似下面的事情。

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

然后我知道它创建了一组get和setter方法。我想做的是,当创建这些方法时,我希望为setter方法指定一些值。提前谢谢。

uxhixvfz

uxhixvfz1#

attr_accessor没有嵌入魔法。对于传递给它的每个参数,它基本上执行如下所示的操作(代码被简化并且缺少必要的检查等):

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

这就是说,attr_accessor :var1, :var2 DSL只是带来了新的4种普通的、老的、好的Ruby方法。对于您所问的问题,您可能需要注意定义这些方法(或者其中一些,或者一个都不定义)本身。例如,对于带有支票的繁琐设置,人们可能会这样做:

attr_reader :variable # reader is reader, no magic

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

上面的代码和往常一样被称为:

instance.variable = 42

# ⇒ 42

instance.variable = nil

# ⇒ ArgumentError: You must be kidding
chhkpiq4

chhkpiq42#

以下是这方面的另一个可能实现:

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

相关问题