Rails 中关联的空对象模式 [英] Null Object Pattern for associations in Rails
问题描述
尽管在此处查看了有关 Rails 中空对象的一些答案,但我似乎无法让它们工作.
Despite looking at a few answers here regarding Null Objects in rails, I can't seem to get them to work.
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.
My problem is that on User creation, I pass in the proper nested attributes (profile_attributes) for the Profile and I end up with a NullProfile on my new User.
我猜这意味着我的自定义配置文件方法在创建时被调用并返回一个 NullProfile.我如何正确执行此 NullObject 以便这仅在读取时发生,而不是在对象的初始创建时发生.
I am guessing that this means that my custom profile method is getting called on create and returning a NullProfile. How do I do this NullObject properly so that this only happens on read and not on the initial creation of the objects.
推荐答案
我正在经历,如果它不存在,我想要一个干净的新对象(如果你这样做只是这样 object.display
不会出错,也许 object.try(:display)
更好)这也是我发现的:
I was going exactly through and I wanted a clean new object if it wasn't present(if you're doing this just so object.display
doesn't err maybe object.try(:display)
is better) this too and this is what I found:
1:别名/alias_method_chain
1: alias/alias_method_chain
def profile_with_no_nill
profile_without_no_nill || NullProfile
end
alias_method_chain :profile, :no_nill
但是由于 alias_method_chain 已被弃用,如果您仍然处于边缘,则必须自己手动完成模式... 这里的答案 似乎提供了更好更优雅的解决方案
But since alias_method_chain is being deprecated, if you're staying on the edge you would have to do the pattern by yourself manually... The answer here seems to provide the better and more elegant solution
2(答案的简化/实用版本):
2(Simplified/practical version from the answer):
class User < ActiveRecord::Base
has_one :profile
accepts_nested_attributes_for :profile
module ProfileNullObject
def profile
super || NullProfile
end
end
include ProfileNullObject
end
注意:你做这件事的顺序(在链接的答案中解释)
note: The order you do this matter(explained in the linked answer)
关于你的尝试:
当你这样做
def profile
@profile || NullProfile
end
它不会像预期的那样表现,因为协会是延迟加载的(除非你告诉它在搜索中 :include
它),所以 @profile 为零,这就是为什么你总是得到空配置文件
It won't behave as expected because the Association is lazily loaded(unless you told it to :include
it in the search), so @profile is nil, that's why you're always getting NullProfile
def profile
self.profile || NullProfile
end
它会失败,因为方法正在调用自己,所以它就像一个递归方法,你得到 SystemStackError: stack level too deep
It will fail because the method is calling itself, so it's sort like a recursive method, you get SystemStackError: stack level too deep
这篇关于Rails 中关联的空对象模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!