重写ActiveRecord属性方法

我正在谈论的一个例子是:

class Person < ActiveRecord::Base def name=(name) super(name.capitalize) end def name super().downcase # not sure why you'd do this; this is just an example end end 

这似乎工作,但我刚刚阅读的重写属性方法在ActiveRecord :: Base文档的部分 ,它build议使用read_attributeread_attribute方法。 我认为在上面的例子中我一定会有什么不对的; 否则,为什么他们会保佑这些方法成为覆盖属性方法的“正确方法”呢? 他们也迫使一个更加丑陋的成语,所以一定有一个很好的理由…

我真正的问题:这个例子有什么问题吗?

回应Gareth的评论…你的代码不会像书面的那样工作。 应该这样改写:

 def name=(name) write_attribute(:name, name.capitalize) end def name read_attribute(:name).downcase # No test for nil? end 

作为Aaron Longwell的答案的扩展,您也可以使用“散列符号”访问已覆盖访问器和增变器的属性:

 def name=(name) self[:name] = name.capitalize end def name self[:name].downcase end 

http://errtheblog.com/posts/18-accessor-missing上有关于此主题的一些很好的信息。;

不pipe多长时间,ActiveRecord都能正确处理ActiveRecord属性访问器的超级调用。

我有一个轨道插件,使得超级如你所期望的超越工作。 你可以在github上find它。

安装:

 ./script/plugin install git://github.com/chriseppstein/has_overrides.git 

使用:

 class Post < ActiveRecord::Base has_overrides module Overrides # put your getter and setter overrides in this module. def title=(t) super(t.titleize) end end end 

一旦你做完了这些事情,只是工作:

 $ ./script/console Loading development environment (Rails 2.3.2) >> post = Post.new(:title => "a simple title") => #<Post id: nil, title: "A Simple Title", body: nil, created_at: nil, updated_at: nil> >> post.title = "another simple title" => "another simple title" >> post.title => "Another Simple Title" >> post.update_attributes(:title => "updated title") => true >> post.title => "Updated Title" >> post.update_attribute(:title, "singly updated title") => true >> post.title => "Singly Updated Title"