Rails 中关联的空对象模式 [英] Null Object Pattern for associations in Rails

查看:31
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆