ActiveRecordモデルのゲッターメソッドを上書きするにはどうすればよいですか?


98

ActiveRecordモデルのゲッターメソッドを上書きしようとしています。nameモデルCategoryでと呼ばれる属性があり、次のようなことができるようにしたいと思います。

def name
  name_trans || name
end

name_trans属性がnilでない場合はそれを返し、そうでない場合は属性を返しnameます。どうすればいいですか?

これは通常、次のように呼び出されます。

@category.name

回答:


123

Railsのスタイルガイドを使用することをお勧めしますself[:attr]以上read_attribute(:attr)

次のように使用できます。

def name
  name_trans || self[:name]
end

なぜそれが良いのですか?他のサイトにリンクするだけでなく、関連するビットをここに含めてください。リンクが無効になる可能性がある
JamesT

2
もう少しコンテキストについては、こちらを参照してください:github.com/bbatsov/rails-style-guide/issues/155
mimsugara

98

更新:Railsスタイルガイドによる推奨される方法はself[:name]read_attributeおよびの代わりに使用することですwrite_attribute。私の答えをスキップして、代わりにこれを選ぶことをお勧めします。


read_attribute名前属性の値を実際にフェッチし、nameメソッドへの再帰的な呼び出しを回避するために使用する必要があることを除いて、それはまったく同じように行うことができます。

def name 
  name_trans || read_attribute(:name)
end

2
Rubocopが好む理由はself[:name]read_attribute[:name]ですか?
Zack Xu

18

getterメソッドを上書きするための別のオプションを追加したいと思います。それは単に:superです。

def name
  name_trans || super
end

これは、属性の取得メソッドだけでなく、関連付けの取得メソッドでも機能します。


1
:これは、Railsは現在、ゲッターとセッターのために、お勧めガイド何であるapi.rubyonrails.org/classes/ActiveRecord/...
sandre89

5

ゲッターのオーバーライドと使用read_attributeは関連付けには機能しませんが、alias_method_chain代わりに使用できます。

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

適切な例を挙げてください...?
Arup Rakshit、2015年

上手。私はちょうどドコを見ました。ここnameで、モデルオブジェクトを呼び出すと、どちらが呼び出されますか- name_with_overrideまたはname_without_override
Arup Rakshit、2015年

1
nameが呼び出されますname_with_override。何らかの理由で元のメソッドを呼び出したい場合は、を呼び出すことができますname_without_override
Patrick Oscity、2015年

OI see ..ご返信ありがとうございます//
Arup Rakshit

2

このようなストア属性を使用している場合

store :settings, accessors: [:volume_adjustment] 

またはgem linkのようなgemを使用する hstore_accessor

つまりstore、モデルのメソッドを使用してしまい、使用できないメソッドをオーバーライドするにはself.read_attribute、代わりに次のsuperように使用する必要があります。

def partner_percentage
  super.to_i || 10
end

0

誰かname_transがgetterメソッドの後で値を更新したい場合は、self [:name] =を使用できます。

def name
  self[:name] = name_trans || self[:name]
  # don't do this, it will cause endless loop
  # update(name: name_trans)
end

0

Railsのread_attributeメソッドを使用できます。 Railsのドキュメント


このリンクは質問に回答する可能性がありますが、リンクのみの回答はSOでは許可されていません。そのリンクの背後にあるものから、回答にコンテキストを追加してください。ありがとう!:)
AJT82 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.