web-dev-qa-db-ja.com

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 docs の属性メソッドのオーバーライドに関するセクションを読んだばかりで、read_attributeおよびwrite_attributeメソッド。上記の例でやっていることには何か間違っているに違いないと思った。そうでなければ、なぜこれらのメソッドを属性メソッドをオーバーライドする「正しい方法」として祝福するのでしょうか?彼らはまた、はるかにugいイディオムを強制しているので、正当な理由がなければなりません...

私の本当の質問:この例には何か問題がありますか?

147
Require This

Garethのコメントをエコーし​​ています...コードは記述どおりに機能しません。次のように書き換える必要があります。

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

def name
  read_attribute(:name).downcase  # No test for nil?
end
208
Aaron Longwell

アーロン・ロングウェルの答えの拡張として、「ハッシュ表記」を使用して、オーバーライドされたアクセサーとミューテーターを持つ属性にアクセスすることもできます。

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

def name
  self[:name].downcase
end
91
mipadi

http://errtheblog.com/posts/18-accessor-missing で、このトピックに関するすばらしい情報を入手できます。

その長短は、ActiveRecordがActiveRecord属性アクセサーのスーパーコールを正しく処理することです。

7
jcnnghm