ActiveRecordモデルのゲッターメソッドを上書きしようとしています。モデルname
にCategory
という属性があり、次のようなことができるようにしたいと思います。
def name
name_trans || name
end
name_trans
属性がnilでない場合はそれを返し、そうでない場合はname
属性を返します。どうすればいいですか?
これは、通常、次のように呼び出す必要があります。
@category.name
Rails Style Guide は、read_attribute(:attr)
よりもself[:attr]
の使用を推奨しています。
次のように使用できます。
def name
name_trans || self[:name]
end
更新: Rails Style Guide による好ましい方法は、self[:name]
およびread_attribute
の代わりにwrite_attribute
を使用することです。私の答えをスキップして、代わりに this one を選ぶことをお勧めします。
read_attribute
を使用してname属性の値を実際にフェッチし、name
メソッドの再帰呼び出しを回避する必要があることを除いて、まったく同じように行うことができます。
def name
name_trans || read_attribute(:name)
end
Getterメソッドを上書きするための別のオプションを追加したいと思います。これは単にsuperです。
def name
name_trans || super
end
これは、属性ゲッターメソッドだけでなく、関連付けゲッターメソッドでも機能します。
ゲッターをオーバーライドしてread_attribute
を使用しても関連付けには機能しませんが、代わりにalias_method_chain
を使用できます。
def name_with_override
name_trans || name_without_override
end
alias_method_chain :name, :override
このようなストア属性を使用する場合
store :settings, accessors: [:volume_adjustment]
またはhstore_accessor
gem link のようなgemを使用します
したがって、モデルでstore
メソッドを使用することになり、self.read_attribute
を使用できないメソッドをオーバーライドするには、代わりにsuper
を使用する必要があります。
def partner_percentage
super.to_i || 10
end
ゲッターメソッドで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
Rails read_attributeメソッドを使用できます。 Rails docs