7

可能重复:
attr_accessor default values如何初始化'attr_accessor'属性值?

我使用on Rails的3.0.9 Ruby和我想从ActiveRecord::Base继承我的类\模型初始化一些attr_accessor属性值。也就是说,

...我的模块中我有:

class User < ActiveRecord::Base 
    attr_accessor :attribute_name1, 
       :attribute_name2, 
       :attribute_name3, 
       ... 
end 

我想设置为true所有attr_accessor属性值我该怎么做?

请注意:当然,我想解决上述问题,以接近“àla Ruby on Rails Way”。我知道after_initialize回调,但通过使用该方法,我应该重复每个attribute_name<N>声明,我希望在该声明中将该值设置为true(...并且这是而不是 DRY - 不要重复自己) 。也许有更好的方法来实现这一点。 当你声明这些属性时,有没有办法设置attr_accessor属性值“实时”?也就是说,我希望立即声明并设置attr_accessor属性!

+0

是有名字(1,2 ...)背后真正的逻辑是什么? – apneadiving

+0

@apneadiving - 是的,当然。 – Backo

回答

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 

由于您的默认值是一个不可变类型(boolean),这种方法的形式在这里使用是安全的。但是如果默认值是一个可变对象(包括数组或字符串),请不要使用它,因为所有新模型对象都将共享完全相同的实例,这可能不是您想要的。

相反,attr_accessor_with_default将接受一个块,在那里你可以每次都返回一个新的实例:

attr_accessor_with_default(:attribute_name) { FizzBuzz.new } 
+5

当前读者注意到'attr_accessor_with_default'已被弃用,从Rails 3.2开始 –

11

你尝试:

class User < ActiveRecord::Base 
    attr_accessor :attribute_name1, 
       :attribute_name2, 
       :attribute_name3, 
       ... 

    after_initialize :set_attr 

    def set_attr 
    @attribute_name1 = true 
    ... 
    end 
end 
+0

我更新了问题(最后请阅读“P.S .:”)。 – Backo

+0

@Backo,这里是一切干得不错答案 – fl00r

+0

@apneadiving - 有没有一种方法来设置'attr_accessor'属性值“动态”当你说明这些? – Backo

3

我只想定义懒洋洋地加载你感兴趣的值的getter ,并使用attr_writer来定义setter。

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}" 

这样做是因为,通常情况下,计算的默认值不会有任何副作用:例如,

class Cat 
    attr_writer :amount_of_feet 
    def amount_of_feet; @amount_of_feet ||= 4; end # usually true 
end 

其中,如果你是说真的,可以用一些元编程改写使订单变得重要,并且直到您第一次尝试访问它时才需要计算该值。

(克林是我的猫,他做得很好,并且仍然有他的脚四)