如何延迟设置 Mongoid 关联

How to lazy-set Mongoid association

我有两个通过 has_one 关系关联的模型。我们还有一个初始化关联的回调。 classes 看起来(大致)像这样:

class User
  has_one :relevance, class_name: 'User::Relevance', inverse_of: :user, dependent: :destroy
  after_create :initialize_relevance

  def initialize_relevance
    self[:relevance] = User::Relevance.new
  end

  # other garbage that *should* be irrelevant
end

class User::Relevance
  belongs_to :user, inverse_of: :relevance, index: true

  # more other garbage that *should* be irrelevant
end

有时相关性关联会进入一个 wonked 状态,即它为零。发生这种情况时,我们希望在调用时重新初始化关系,并 return 它而不是 nil。所以在 class User 中,我们会有这样的:

def relevance
  self[:relevance] = User::Relevance.new if self[:relevance].nil?

  self[:relevance]
end

除非这不起作用,nil 仍然是 returned。我也对 update_attribute(User::Relevance.new)self.create_relevance 进行了相同的尝试,但 nil 似乎总是 returned。不太确定从这里去哪里,会喜欢任何想法。如果有帮助,我还可以提供更多代码或示例。

其他详细信息

您可以尝试在 getter 方法中构建 relevance,而不是在回调中设置关联:

class User
  def relevance
    self[:relevance] || User::Relevance.new
  end
end

这里很好地描述了这种模式:http://blog.arkency.com/2016/07/always-present-association/

Mongoid 支持自动建立一对一关系。这应该有所帮助(不需要钩子或 getter 覆盖)。

has_one :relevance, 
        class_name: 'User::Relevance', 
        inverse_of: :user, 
        dependent: :destroy, 
        autobuild: true

正如选项名称所暗示的那样,relevance 将 spring 在访问时生效(如果在访问之前为 nil)。

此外,您知道这种方式不会保留相关性,对吗?

  after_create :initialize_relevance

  def initialize_relevance
    self[:relevance] = User::Relevance.new
  end

难怪 returns nil 稍后。