如何初始化’attr_accessor’属性值?
可能重复:
attr_accessor默认值
我正在使用Ruby on Rails 3.0.9,我想在我的class \ model中初始化一些inheritance自ActiveRecord::Base
attr_accessor
属性值。 那是,
…在我的模块中我有:
class User < ActiveRecord::Base attr_accessor :attribute_name1, :attribute_name2, :attribute_name3, ... end
我想将所有attr_accessor
属性值设置为true
。 我怎样才能做到这一点?
PS:当然我想解决上述问题,接近“Ruby on Rails Way”。 我知道after_initialize
回调但是通过使用该方法我应该重复每个attribute_name
语句,我想在after_initialize
语句中将值设置为true
(…这不是 DRY – 不要重复自己)。 也许有更好的方法来实现这一目标。 当您声明这些属性时,有没有办法“动态”设置attr_accessor
属性值? 也就是说,我希望立刻声明并设置attr_accessor
属性!
对于Rails 3.2或更早版本,您可以使用attr_accessor_with_default
:
class User < ActiveRecord::Base attr_accessor_with_default :attribute_name1, true attr_accessor_with_default :attribute_name2, true attr_accessor_with_default :attribute_name3, true ... end
由于您的默认值是不可变类型(布尔值),因此此方法的forms在此处可以安全使用。 但是如果默认值是可变对象(包括数组或字符串),请不要使用它,因为所有新模型对象将共享完全相同的实例,这可能不是您想要的。
相反, attr_accessor_with_default
将接受一个块,您可以在每次返回一个新实例:
attr_accessor_with_default(:attribute_name) { FizzBuzz.new }
你试过了吗:
class User < ActiveRecord::Base attr_accessor :attribute_name1, :attribute_name2, :attribute_name3, ... after_initialize :set_attr def set_attr @attribute_name1 = true ... end end
我只想定义一个懒惰加载你感兴趣的值的getter,并使用attr_writer
来定义setter。 例如,
class Cat attr_writer :amount_of_feet def amount_of_feet; @amount_of_feet ||= 4; end # usually true end
如果你的意思是,可以用一些元编程重写:
class Cat # The below method could be defined in Module directly def self.defaulted_attributes(attributes) attributes.each do |attr, default| attr_writer attr define_method(attr) do instance_variable_get("@#{attr}") || instance_variable_set("@#{attr}", default) end end end defaulted_attributes :amount_of_feet => 4 end calin = Cat.new print "calin had #{calin.amount_of_feet} feet... " calin.amount_of_feet -= 1 puts "but I cut one of them, he now has #{calin.amount_of_feet}"
这是有效的,因为通常,计算默认值不会产生任何副作用,使得订单很重要,在您首次尝试访问它之前,不需要计算该值。
(Câlin是我的猫;他表现很好,仍然有四个脚)
残酷的解决方案
class User < ActiveRecord::Base @@attr_accessible = [:attribute_name1, :attribute_name2, :attribute_name3] attr_accessor *@@attr_accessible after_initialize :set_them_all def set_them_all @@attr_accessible.each do |a| instance_variable_set "@#{a}", true end end end
或者更多概念: Ruby:attr_accessor生成的方法 - 如何迭代它们(在to_s中 - 自定义格式)?