我正在使用Ruby on Rails 3.0.9,我想在我的类\ model中初始化一些继承自attr_accessor
的{{1}}属性值。也就是说,
...在我的模块中我有:
ActiveRecord::Base
和我想设置class User < ActiveRecord::Base
attr_accessor :attribute_name1,
:attribute_name2,
:attribute_name3,
...
end
所有true
属性值。 我该怎么做?
P.S。:当然我想解决上述问题,接近“Ruby on Rails Way”。我知道attr_accessor
回调,但是通过使用该方法,我应该重复每个after_initialize
语句,我想在attribute_name<N>
语句中将值设置为true
(。 ..这是不干 - 不要重复自己)。也许有更好的方法来实现这一目标。 当您说明这些属性时,是否可以“动态”设置after_initialize
属性值?也就是说,我希望一次声明并设置attr_accessor
属性!
答案 0 :(得分:12)
你有没有尝试过:
class User < ActiveRecord::Base
attr_accessor :attribute_name1,
:attribute_name2,
:attribute_name3,
...
after_initialize :set_attr
def set_attr
@attribute_name1 = true
...
end
end
答案 1 :(得分:6)
对于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
由于您的默认值是不可变类型(布尔值),因此此方法的这种形式在此处可以安全使用。但是如果默认值是一个可变对象(包括数组或字符串),请不要使用它,因为所有新模型对象都将共享完全相同的实例,这可能不是您想要的。
相反,attr_accessor_with_default
将接受一个块,每次都可以返回一个新实例:
attr_accessor_with_default(:attribute_name) { FizzBuzz.new }
答案 2 :(得分:3)
我只想定义一个懒惰加载你感兴趣的值的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是我的猫;他表现不错,仍有四只脚)
答案 3 :(得分:2)
残酷的解决方案
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 generated methods - how to iterate them (in to_s - custom format)?