だから私はActiveRecordオブジェクトの属性のデフォルトのgetterをオーバーライドする方法を知っています
def custom_getter
return self[:custom_getter] || some_default_value
end
同じことを達成しようとしていますが、所属団体に所属しています。例えば。
class Foo < AR
belongs_to :bar
def bar
return self[:bar] || Bar.last
end
end
class Bar < AR
has_one :foo
end
私が言ったら:
f = Foo.last
メソッドf.bar
その関連付けがまだ存在しない場合、nilではなく、最後のバーを返します。
ただし、これは機能しません。その理由は、self [:bar]は常に未定義であるためです。それは実際にはself [:bar_id]です。
私は次のような素朴なことをすることができます:
def bar
if self[:bar_id]
return Bar.find(self[:bar_id])
else
return Bar.last
end
end
ただし、Barがすでにフェッチされている場合でも、これは常にdb呼び出しを行います。これは確かに理想的ではありません。
誰かが、belongs_to属性が1度だけロードされ、設定されていない場合はデフォルト値を持つような関係を持つ方法について洞察がありますか?.
alias_methodはあなたの友達です。
alias_method :original_bar, :bar
def bar
self.original_bar || Bar.last
end
これが機能する方法は、デフォルトの「バー」メソッドを「元のバー」としてエイリアスし、独自のバージョンの「バー」を実装することです。 original_barの呼び出しがnilを返す場合は、代わりに最後のBarインスタンスを返します。
「スーパー」を使用するのが最善の方法であることがわかりました
def bar
super || Bar.last
end
これがあなたのお役に立てば幸いです:D
ランディの答えはスポットですが、alias_method_chainを使用してそれを書く簡単な方法があります:
def bar_with_default_find
self.bar_without_default_find || Bar.last
end
alias_method_chain :bar, :default_find
これにより2つのメソッドが作成されます-bar_with_default_find
およびbar_without_default_find
とbar
メソッドのエイリアスwith
。これにより、どちらか一方を明示的に呼び出すか、デフォルトのままにすることができます。