web-dev-qa-db-ja.com

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

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

def name
  name_trans || name
end

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

これは、通常、次のように呼び出す必要があります。

@category.name
88
oyvindhauge

Rails Style Guide は、read_attribute(:attr)よりもself[:attr]の使用を推奨しています。

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

def name
  name_trans || self[:name]
end
102
Wonsup Lee

更新: Rails Style Guide による好ましい方法は、self[:name]およびread_attributeの代わりにwrite_attributeを使用することです。私の答えをスキップして、代わりに this one を選ぶことをお勧めします。


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

def name 
  name_trans || read_attribute(:name)
end
97
meagar

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

def name
  name_trans || super
end

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

14
lei liu

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

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override
5
Patrick Oscity

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

store :settings, accessors: [:volume_adjustment] 

またはhstore_accessorgem link のようなgemを使用します

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

def partner_percentage
  super.to_i || 10
end
2
onemanstartup

ゲッターメソッドでname_transの後の値を更新する場合は、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
fangxing

Rails read_attributeメソッドを使用できます。 Rails docs

0
Rajat Bansal