bra*_*rad 47 activerecord ruby-on-rails associations default-value
所以我知道如何覆盖ActiveRecord对象的属性的默认getter
def custom_getter
return self[:custom_getter] || some_default_value
end
Run Code Online (Sandbox Code Playgroud)
我试图实现相同的东西,但属于一个属于协会.例如.
class Foo < AR
belongs_to :bar
def bar
return self[:bar] || Bar.last
end
end
class Bar < AR
has_one :foo
end
Run Code Online (Sandbox Code Playgroud)
当我说:
f = Foo.last
Run Code Online (Sandbox Code Playgroud)
我想让方法f.bar
返回最后一个Bar,而不是nil,如果该关联还不存在.
但这不起作用.原因是self [:bar]总是未定义的.它实际上是自我[:bar_id].
我可以做一些天真的事情:
def bar
if self[:bar_id]
return Bar.find(self[:bar_id])
else
return Bar.last
end
end
Run Code Online (Sandbox Code Playgroud)
但是,即使已经获取了Bar,这也总是会进行db调用,这当然不是理想的.
有没有人能够了解我如何建立关系,以便belongs_to属性只加载一次,如果没有设置则具有默认值.
Ran*_*mon 71
alias_method是你的朋友.
alias_method :original_bar, :bar
def bar
self.original_bar || Bar.last
end
Run Code Online (Sandbox Code Playgroud)
这样做的方法是将默认的"bar"方法别名为"原始栏",然后实现自己的"bar"版本.如果对original_bar的调用返回nil,则返回最后一个Bar实例.
alx*_*bra 22
我发现使用"超级"是最好的方法
def bar
super || Bar.last
end
Run Code Online (Sandbox Code Playgroud)
我希望这会对你有所帮助:D
Cor*_*Foy 10
Randy的答案很明显,但使用alias_method_chain可以更轻松地编写它:
def bar_with_default_find
self.bar_without_default_find || Bar.last
end
alias_method_chain :bar, :default_find
Run Code Online (Sandbox Code Playgroud)
这就产生了两个方法- bar_with_default_find
与bar_without_default_find
和别名bar
的with
方法.这样你就可以明确地调用其中一个,或者只保留默认值.