在 Ruby on Rails 中重写 setter 方法的正确方法是什么? [英] What is the right way to override a setter method in Ruby on Rails?
问题描述
我正在使用 Ruby on Rails 3.2.2,我想知道以下是否是覆盖我的类属性的 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 日
现在 Rails文档 还建议像这样使用 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
因此,您的第一种方法是在 Models of 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屋!