在Ruby on Rails中重写setter方法的正确方法是什么? [英] What is the right way to override a setter method in Ruby on Rails?
问题描述
我正在使用Ruby on Rails 3.2.2,我想知道以下内容是否是正确"/正确"/确定"方式来覆盖我的class属性的setter方法.
I am using Ruby on Rails 3.2.2 and I would like to know if the following is a "proper"/"correct"/"sure" way to override a setter method for a my class attribute.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
上面的代码似乎按预期工作.但是,我想知道,通过使用上面的代码,将来我是否会遇到问题,或者至少会遇到Ruby on Rails我应该期望"/可能会发生"的问题.如果那不是重写setter方法的正确方法,那么正确的方法是什么?
The above code seems to work as expected. However, I would like to know if, by using the above code, in future I will have problems or, at least, what problems "should I expect"/"could happen" with Ruby on Rails. If that isn't the right way to override a setter method, what is the right way?
注意:如果我使用代码
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self.attribute_name = value
end
我收到以下错误:
SystemStackError (stack level too deep):
actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70
推荐答案
============================== ======================================== 更新:2017年7月19日
=========================================================================== Update: July 19, 2017
现在导轨文档还建议像这样使用super
:
Now the Rails documentation is also suggesting to use super
like this:
class Model < ActiveRecord::Base
def attribute_name=(value)
# custom actions
###
super(value)
end
end
============================================== ==============================
原始答案
如果要在通过模型访问时覆盖表的列的setter方法,则可以采用这种方法.
If you want to override the setter methods for columns of a table while accessing through models, this is the way to do it.
class Model < ActiveRecord::Base
attr_accessible :attribute_name
def attribute_name=(value)
# custom actions
###
write_attribute(:attribute_name, value)
# this is same as self[:attribute_name] = value
end
end
请参见覆盖默认值访问器在Rails文档中.
See Overriding default accessors in the Rails documentation.
因此,您的第一种方法是重写Ruby on Rails模型中列设置器的正确方法. Rails已经提供了这些访问器,以访问表的列作为模型的属性.这就是我们所谓的ActiveRecord ORM映射.
So, your first method is the correct way to override column setters in Models of Ruby on Rails. These accessors are already provided by Rails to access the columns of the table as attributes of the model. This is what we call ActiveRecord ORM mapping.
还请记住,模型顶部的 attr_accessible
与访问器无关.它具有完全不同的功能(请参见
Also keep in mind that the attr_accessible
at the top of the model has nothing to do with accessors. It has a completely different functionlity (see this question)
但是在纯Ruby中,如果您为一个类定义了访问器,并且想覆盖setter,则必须使用这样的实例变量:
But in pure Ruby, if you have defined accessors for a class and want to override the setter, you have to make use of instance variable like this:
class Person
attr_accessor :name
end
class NewPerson < Person
def name=(value)
# do something
@name = value
end
end
一旦您知道attr_accessor
的作用,这将更容易理解.代码attr_accessor :name
等效于这两种方法(getter和setter)
This will be easier to understand once you know what attr_accessor
does. The code attr_accessor :name
is equivalent to these two methods (getter and setter)
def name # getter
@name
end
def name=(value) # setter
@name = value
end
第二种方法也会失败,因为在该方法中调用同一方法attribute_name=
时,它将导致无限循环.
Also your second method fails because it will cause an infinite loop as you are calling the same method attribute_name=
inside that method.
这篇关于在Ruby on Rails中重写setter方法的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!