Ruby on rails rails覆盖关系的默认getter(属于)

Ruby on rails rails覆盖关系的默认getter(属于),ruby-on-rails,activerecord,associations,default-value,Ruby On Rails,Activerecord,Associations,Default Value,因此,我知道如何使用 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 我希

因此,我知道如何使用

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.bar
返回最后一个条,而不是nil(如果该关联还不存在)

然而,这不起作用。原因是self[:bar]始终未定义。它实际上是self[:bar\u id]

我可以做一些天真的事情,比如:

def bar
  if self[:bar_id]
    return Bar.find(self[:bar_id])
  else
    return Bar.last
  end
end
然而,这将始终进行db调用,即使已经获取了Bar,这肯定不是理想的


是否有人了解我如何建立一种关系,使“属于”属性只加载一次,如果未设置,则具有默认值。

alias\u方法是您的朋友

alias_method :original_bar, :bar
def bar
  self.original_bar || Bar.last
end

其工作方式是将默认的“bar”方法别名为“原始bar”,然后实现自己的“bar”版本。如果对original_bar的调用返回nil,那么您将返回最后一个bar实例。

Randy的答案是正确的,但是有一种更简单的方法来编写它,使用alias_方法\u chain:


def bar_with_default_find
  self.bar_without_default_find || Bar.last
end
alias_method_chain :bar, :default_find
这将创建两种方法-
bar\u和
bar\u(带
bar\u(不带
和别名
bar
方法。这样,您可以显式地调用其中一个,或者只保留默认值。

我发现使用“super”是最好的方法

def bar
  super || Bar.last
end

我希望这对你有帮助:D

你没有循环吗?因为在酒吧里叫酒吧?不,你叫“原始酒吧”,这是“酒吧”的新名字。有一件事让我大吃一惊,要记住在新的别名方法之前调用别名方法。新的别名方法第3行不能仅仅是
原始的| | |条。last
更好:
超级| |条。last
很酷的解决方案,因为您可以使用
\u而不使用默认的_查找
来了解原始的关联方法。是我唯一能找到工作的人。谢谢,我相信现在不推荐使用
alias\u method\u chain
。这是一个非常好的答案,因为它只使用了普通的旧Ruby继承。这比公认的答案简单得多。
def bar
  super || Bar.last
end