尽管在这里看到了关于Rails中的Null Objects的一些答案,但我似乎无法使它们正常工作。

class User < ActiveRecord::Base
  has_one :profile
  accepts_nested_attributes_for :profile

  def profile
    self.profile || NullProfile #I have also tried
    @profile || NullProfile #but it didn't work either
  end
end

class NullProfile
  def display #this method exists on the real Profile class
    ""
  end
end

class UsersController < ApplicationController
  def create
    User.new(params)
  end
end

我的问题是在创建用户时,我为配置文件传递了适当的嵌套属性(profile_attributes),最后在新用户上获得了一个NullProfile。

我猜这意味着我的自定义配置文件方法在创建时被调用并返回NullProfile。我如何正确地执行此NullObject,以使其仅在读取时发生,而不在对象的初始创建时发生。

最佳答案

我正在仔细检查,如果没有它,我想要一个干净的新对象(如果这样做的话,object.display不会出错,也许object.try(:display)更好),这也是我发现的:

1:别名/alias_method_chain

def profile_with_no_nill
  profile_without_no_nill || NullProfile
end
alias_method_chain :profile, :no_nill

但是由于alias_method_chain已被弃用,所以如果您处于边缘状态,则必须手动手动执行模式... The answer here似乎提供了更好,更优雅的解决方案

2(答案的简体/实际版本):
class User < ActiveRecord::Base
  has_one :profile
  accepts_nested_attributes_for :profile

  module ProfileNullObject
    def profile
      super || NullProfile
    end
  end
  include ProfileNullObject
end

注意:您执行此操作的顺序(在链接的答案中有解释)

关于您尝试的内容:

你什么时候做
def profile
  @profile || NullProfile
end

它不会像预期的那样工作,因为该关联是延迟加载的(除非您在搜索中告诉它将它:include编码),所以@profile为nil,这就是为什么您总是得到NullProfile的原因
def profile
  self.profile || NullProfile
end

它将失败,因为该方法正在调用自身,所以它有点像递归方法,您会得到SystemStackError: stack level too deep

09-30 20:30