尽管在这里看到了关于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