Ruby on rails 3 Rails中关联的空对象模式
尽管在这里看到了一些关于rails中空对象的答案,但我似乎无法让它们正常工作Ruby on rails 3 Rails中关联的空对象模式,ruby-on-rails-3,null-object-pattern,Ruby On Rails 3,Null Object Pattern,尽管在这里看到了一些关于rails中空对象的答案,但我似乎无法让它们正常工作 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 ei
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
class用户
我的问题是,在创建用户时,我为配置文件传入了正确的嵌套属性(profile_属性),最终在我的新用户上得到了一个null配置文件
我猜这意味着我的自定义概要文件方法在创建并返回NullProfile时被调用。如何正确处理这个空对象,使其仅在读取时发生,而不是在对象的初始创建时发生。我正在仔细检查,如果它不存在,我想要一个干净的新对象(如果您这样做
对象。display
不会出错,可能对象。尝试(:display)
更好)这也是我发现的:
1:别名/别名\u方法\u链
def profile_with_no_nill
profile_without_no_nill || NullProfile
end
alias_method_chain :profile, :no_nill
但是,由于alias_method_chain已被弃用,如果您处于边缘,则必须自己手动完成该模式。。。似乎提供了更好、更优雅的解决方案
2(答案中的简化/实用版本):
它的行为不会像预期的那样,因为关联是延迟加载的(除非你告诉它在搜索中包含它),所以@profile是nil,这就是为什么你总是得到NullProfile
def profile
self.profile || NullProfile
end
它将失败,因为该方法正在调用自身,所以它的排序类似于递归方法,您会得到
SystemStackError:stack level太深
而不是使用别名\u方法\u链,请使用以下命令:
def profile
self[:profile] || NullProfile.new
end
我发现了一个比在接受的答案中包含私有模块更简单的选项 您可以重写reader方法,并使用
association
方法从ActiveRecord
获取关联对象
class User < ApplicationRecord
has_one :profile
def profile
association(:profile).load_target || NullProfile
end
end # class User
class用户
根据Rails,关联方法被加载到模块中,因此重写它们是安全的
所以,有点像
def profile
super || NullProfile.new
end
应该对你有用
class User < ApplicationRecord
has_one :profile
def profile
association(:profile).load_target || NullProfile
end
end # class User
def profile
super || NullProfile.new
end