=================================================== =========================
更新:2017 年 7 月 19 日
Now the Rails 文档 http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Overwriting+default+accessors还建议使用super
像这样:
class Model < ActiveRecord::Base
def attribute_name=(value)
# custom actions
###
super(value)
end
end
=================================================== =========================
原答案
如果您想在通过模型访问时覆盖表列的 setter 方法,可以采用这种方法。
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
See 覆盖默认访问器 http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Overwriting+default+accessors在 Rails 文档中。
因此,您的第一个方法是在 Ruby on Rails 模型中覆盖列设置器的正确方法。 Rails 已经提供了这些访问器来访问表的列作为模型的属性。这就是我们所说的 ActiveRecord ORM 映射。
另请记住,attr_accessible
模型顶部与访问器无关。它具有完全不同的功能(参见这个问题 https://stackoverflow.com/questions/3136420/difference-between-attr-accessor-and-attr-accessible)
但在纯 Ruby 中,如果您已经为类定义了访问器并想要覆盖 setter,则必须使用实例变量,如下所示:
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)
def name # getter
@name
end
def name=(value) # setter
@name = value
end
另外,您的第二个方法也会失败,因为当您调用相同的方法时,它会导致无限循环attribute_name=
在该方法内部。