Ruby-on-rails 如何覆盖 ActiveRecord 模型中的 getter 方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21835116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:22:03  来源:igfitidea点击:

How can I overwrite a getter method in an ActiveRecord model?

ruby-on-railsrubyrails-activerecordgetter-setter

提问by oyvindhauge

I'm trying to overwrite a getter method for an ActiveRecord model. I have an attribute called namein the model Category, and I'd like to be able to do something like this:

我正在尝试覆盖 ActiveRecord 模型的 getter 方法。我name在模型中调用了一个属性Category,我希望能够执行以下操作:

def name
  name_trans || name
end

If name_transattribute is not nil, then return it, else return nameattribute. How would I do this?

如果name_trans属性不为零,则返回它,否则返回name属性。我该怎么做?

This should then be called normally like this:

然后应该像这样正常调用它:

@category.name

回答by Wonsup Lee

The Rails Style Guiderecommends using self[:attr]over read_attribute(:attr).

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

You can use it like this:

你可以这样使用它:

def name
  name_trans || self[:name]
end

回答by meagar

Update: The preferred method according to the Rails Style Guideis to use self[:name]instead of read_attributeand write_attribute. I would encourage you to skip my answer and instead prefer this one.

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



You can do it exactly like that, except that you need to use read_attributeto actually fetch the value of the name attribute and avoid the recursive call to the namemethod:

您可以完全那样做,只是您需要使用read_attribute来实际获取 name 属性的值并避免对name方法的递归调用:

def name 
  name_trans || read_attribute(:name)
end

回答by lei liu

I would like to add another option for overwriting getter method, which is simply :super.

我想再添加一个覆盖getter方法的选项,就是:super。

def name
  name_trans || super
end

this works not just on attributes getter method, but also associations getter methods, too。

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

回答by Patrick Oscity

Overriding the getter and using read_attributedoes not work for associations, but you can use alias_method_chaininstead.

覆盖 getter 和 usingread_attribute对关联不起作用,但您可以alias_method_chain改用。

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

回答by onemanstartup

If you using store attributes like this

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

store :settings, accessors: [:volume_adjustment] 

or using gems like hstore_accessorgem link

或使用 gems 之类的 hstore_accessorgem 链接

So you ended up using storemethod on model, then to override those method you can't use self.read_attribute, you must use instead superlike that:

所以你最终store在模型上使用了方法,然后要覆盖那些你不能使用的方法self.read_attribute,你必须super像这样使用:

def partner_percentage
  super.to_i || 10
end

回答by fangxing

If someone want update the value after name_transin getter method, you could use self[:name]=.

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

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

回答by Rajat Bansal

You can use Rails read_attribute method. Rails docs

您可以使用 Rails read_attribute 方法。 Rails 文档