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 

其中,如果你是說真的,可以用一些元編程改寫使訂單變得重要,並且直到您第一次嘗試訪問它時才需要計算該值。

(克林是我的貓,他做得很好,並且仍然有他的腳四)