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

oyv*_*uge 91 ruby ruby-on-rails getter-setter rails-activerecord

我正在尝试覆盖ActiveRecord模型的getter方法.我name在模型中调用了一个属性Category,我希望能够做到这样的事情:

def name
  name_trans || name
end
Run Code Online (Sandbox Code Playgroud)

如果name_transattribute不是nil,则返回它,否则返回name属性.我该怎么做?

这应该像这样正常调用:

@category.name
Run Code Online (Sandbox Code Playgroud)

小智 107

Rails的风格指南建议使用self[:attr]read_attribute(:attr).

你可以像这样使用它:

def name
  name_trans || self[:name]
end
Run Code Online (Sandbox Code Playgroud)

  • 有关更多信息,请参阅此处:https://github.com/bbatsov/rails-style-guide/issues/155 (2认同)

mea*_*gar 97

更新:根据Rails样式指南的首选方法是使用self[:name]而不是read_attributewrite_attribute.我鼓励你跳过我的答案,而不是喜欢这个.


你可以完全这样做,除了你需要用来read_attribute实际获取name属性的值并避免对name方法的递归调用:

def name 
  name_trans || read_attribute(:name)
end
Run Code Online (Sandbox Code Playgroud)

  • 知道为什么Rubocop更喜欢`self [:name]`而不是`read_attribute [:name]`? (2认同)

lei*_*liu 15

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

def name
  name_trans || super
end
Run Code Online (Sandbox Code Playgroud)

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

  • 这是 Rails 指南目前为 getter 和 setter 推荐的:http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Overwriting+default+accessors (2认同)

Pat*_*ity 5

覆盖getter并使用read_attribute不适用于关联,但您可以使用alias_method_chain.

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override
Run Code Online (Sandbox Code Playgroud)