rails覆盖关系的默认getter(belongs_to)
所以我知道如何覆盖使用的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
返回最后一个酒吧,而不是零,如果该关联不存在。
但是这不起作用。 原因是self [:bar]总是未定义的。 这实际上是自我[:bar_id]。
我可以做一些天真的事情:
def bar if self[:bar_id] return Bar.find(self[:bar_id]) else return Bar.last end end
但是,这总是会调用db调用,即使Bar已经被提取,这当然也不是很理想。
有没有人有一个洞察力,我可能有一个关系,这样的belongs_to属性只加载一次,并有一个默认值,如果没有设置。
alias_method是你的朋友在这里。
alias_method :original_bar, :bar def bar self.original_bar || Bar.last end
这种方式的工作原理是,你将默认的“bar”方法别名为“original bar”,然后实现你自己的“bar”版本。 如果对original_bar的调用返回nil,则返回最后一个Bar实例。
兰迪的答案是现货,但有一个更简单的方法来写它,使用alias_method_chain:
def bar_with_default_find self.bar_without_default_find || Bar.last end alias_method_chain :bar, :default_find
这会创build两个方法bar_with_default_find
和bar_without_default_find
以及别名到with
方法。 这样,你可以明确地调用其中一个,或者保留默认值。
我发现使用“超级”是最好的方法
def bar super || Bar.last end
我希望这可以帮助你:D