如何覆盖ActiveRecord模型中的getter方法?

我正在尝试覆盖ActiveRecord模型的getter方法。 我在模型Category有一个名为name的属性,我希望能够做到这样的事情:

 def name name_trans || name end 

如果name_trans属性不为零,则返回它,否则返回name属性。 我将如何做到这一点?

这应该这样正常地调用:

 @category.name 

Rails风格指南build议使用self[:attr] over read_attribute(:attr)

你可以像这样使用它:

 def name name_trans || self[:name] end 

更新:根据Rails风格指南的首选方法是使用self[:name]而不是read_attributeread_attribute 。 我鼓励你跳过我的回答,而更喜欢这一个 。


除了需要使用read_attribute来实际获取name属性的值并避免对name方法的recursion调用之外,您可以像这样做:

 def name name_trans || read_attribute(:name) end 

我想添加另一个覆盖getter方法的选项,简单地说就是:super。

 def name name_trans || super end 

这不仅适用于属性getter方法,还适用于关联getter方法。

重写getter和使用read_attribute不适用于关联,但是您可以使用alias_method_chain来代替。

 def name_with_override name_trans || name_without_override end alias_method_chain :name, :override 

如果你使用这样的商店属性

 store :settings, accessors: [:volume_adjustment] 

或使用诸如hstore_accessor gem链接之类的gem

所以,你最终在模型上使用store方法,然后重写这些方法,你不能使用self.read_attribute ,你必须使用,而不是像这样:

 def partner_percentage super.to_i || 10 end 

如果有人想在getter方法中更新name_trans之后的值,可以使用self [:name] =。

 def name self[:name] = name_trans || self[:name] # don't do this, it will cause endless loop # update(name: name_trans) end 

你可以使用Rails的read_attribute方法。 Rails文档