覆盖ActiveRecord属性方法

147 oop activerecord ruby-on-rails

我正在谈论的一个例子:

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
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但我刚刚阅读了ActiveRecord :: Base文档中覆盖属性方法的部分,并建议使用read_attributewrite_attribute方法.我认为在上面的例子中我所做的事情肯定有问题; 否则,为什么他们会将这些方法作为覆盖属性方法的"正确方法"?他们也在逼迫一个更丑陋的习语,所以必须有充分的理由......

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

Aar*_*ell 210

回应Gareth的评论......你的代码将无法按照书面形式运作.它应该以这种方式重写:

def name=(name)
  write_attribute(:name, name.capitalize)
end

def name
  read_attribute(:name).downcase  # No test for nil?
end
Run Code Online (Sandbox Code Playgroud)

  • 这不再是真的.超级或现在都有效.但是,我没有测试哈希表示法. (17认同)
  • 在rails 3中,Aaron在这里指定的阅读器方法起作用,但是原始海报指定的作者(将名称提供给super)工作正常,并且哇哇比手工编写属性更干净,如Aaron建议的那样. (2认同)
  • 这在 Rails 6.1 中被删除:https://github.com/rails/rails/commit/e14e78bf447fbe1420d87212e833535a72783cd2 (2认同)

mip*_*adi 91

作为Aaron Longwell答案的扩展,您还可以使用"哈希表示法"来访问具有被覆盖的访问器和更改器的属性:

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

def name
  self[:name].downcase
end
Run Code Online (Sandbox Code Playgroud)


jcn*_*ghm 7

有关此主题的一些很好的信息,请访问http://errtheblog.com/posts/18-accessor-missing.

它的长短是ActiveRecord正确处理ActiveRecord属性访问器的超级调用.