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

时间:2022-10-04 15:37:22

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

我试图覆盖ActiveRecord模型的getter方法。我在模型类别中有一个名为name的属性,我想做这样的事情:

def name
  name_trans || name
end

If name_trans attribute is not nil, then return it, else return name attribute. How would I do this?

如果name_trans属性不是nil,那么返回它,否则返回name属性。我该怎么做呢?

This should then be called normally like this:

通常应该这样称呼它:

@category.name

7 个解决方案

#1


79  

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

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

You can use it like this:

你可以这样使用:

def name
  name_trans || self[:name]
end

#2


94  

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

更新:根据Rails样式指南,首选的方法是使用self[:name]而不是read_attribute和write_attribute。我建议你跳过我的答案,而选择这个。


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

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

def name 
  name_trans || read_attribute(:name)
end

#3


11  

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

我想添加覆盖getter方法的另一个选择,就是:超级。

def name
  name_trans || super
end

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

这样做不仅对属性的getter方法,也是联想的getter方法。

#4


5  

Overriding the getter and using read_attribute does not work for associations, but you can use alias_method_chain instead.

重写getter和使用read_attribute对关联无效,但是可以使用alias_method_chain。

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

#5


2  

If you using store attributes like this

如果您使用像这样的存储属性

store :settings, accessors: [:volume_adjustment] 

or using gems like hstore_accessor gem link

或者使用hstore_accessor gem链接

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

所以你使用了模型上的存储方法,然后重写那些你不能使用self的方法。read_attribute,你必须使用super:

def partner_percentage
  super.to_i || 10
end

#6


0  

If someone want update the value after name_trans in 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

#7


0  

You can use Rails read_attribute method. Rails docs

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

#1


79  

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

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

You can use it like this:

你可以这样使用:

def name
  name_trans || self[:name]
end

#2


94  

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

更新:根据Rails样式指南,首选的方法是使用self[:name]而不是read_attribute和write_attribute。我建议你跳过我的答案,而选择这个。


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

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

def name 
  name_trans || read_attribute(:name)
end

#3


11  

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

我想添加覆盖getter方法的另一个选择,就是:超级。

def name
  name_trans || super
end

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

这样做不仅对属性的getter方法,也是联想的getter方法。

#4


5  

Overriding the getter and using read_attribute does not work for associations, but you can use alias_method_chain instead.

重写getter和使用read_attribute对关联无效,但是可以使用alias_method_chain。

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

#5


2  

If you using store attributes like this

如果您使用像这样的存储属性

store :settings, accessors: [:volume_adjustment] 

or using gems like hstore_accessor gem link

或者使用hstore_accessor gem链接

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

所以你使用了模型上的存储方法,然后重写那些你不能使用self的方法。read_attribute,你必须使用super:

def partner_percentage
  super.to_i || 10
end

#6


0  

If someone want update the value after name_trans in 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

#7


0  

You can use Rails read_attribute method. Rails docs

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