扶手:创建关联,如果没有被发现,避免零误差 [英] Rails: Create association if none is found to avoid nil errors

查看:147
本文介绍了扶手:创建关联,如果没有被发现,避免零误差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,我的用户可以拥有一套preferences。两者都是如下的ActiveRecord的-模型存储:

 类用户的LT; AR :: Base的
   HAS_ONE:preference_set
结束

类preferenceSet< AR :: Base的
   belongs_to的:用户
结束
 

我现在可以访问用户的preferences:

  @u = User.first
@úpreference_set => #< preferenceSet ...>
@úpreference_set.play_sounds =>真正
 

但失败如果尚未创建preference集,因为@ü。preference_set将回到零了,我会叫 play_sounds

我要存档的是用户。preference_set总是返回preferenceSet实例。我试着将其定义是这样的:

 类用户的LT; ..
   HAS_ONE:preference_set

   DEF preference_set
     preference_set || build_ preference_set
   结束
结束
 

这是造成堆栈层次过深,因为它是递归调用本身。

我的问题是这样的:

我如何确保 @用户。preference_set 返回或者相应的preference_set记录或者,如果不存在,建立一个新的<? / P>

我知道我可以只重命名我的协会(例如, preference_set_real ),并避免递归调用此方法,但对于简单起见,在我的应用程序的缘故,我倒是想保持命名。

谢谢!

解决方案

那么做到这一点的最好办法是,当你创建创建相关记录主之一:

 类用户的LT;的ActiveRecord :: Base的
   HAS_ONE:preference_set,:自动保存=&GT;真正
   before_create:build_ preference_set
结束
 

这将设置它,以便每当用户创建,是一所以 preferenceSet 。如果您需要初始化与参数的相关记录,然后调用 before_create 不同的方法,它调用 build_ preference_set(:my_options =&GT ;这里)然后返回

您可以再仅仅通过迭代任何不具有 preferenceSet ,并通过调用#楼1正常化所有现有的记录CREATE_ preference_set

如果您只想创建 preferenceSet 时,它是绝对必要的,那么你可以这样做:

 类用户的LT;的ActiveRecord :: Base的
   HAS_ONE:preference_set

   DEF preference_set_with_initialize
     preference_set_without_initialize || build_ preference_set
   结束

   alias_method_chain:preference_set,:初始化
结束
 

I have an application where my users can have a set of preferences. Both are stored as ActiveRecord-models as follows:

class User < AR::Base
   has_one :preference_set
end

class PreferenceSet < AR::Base
   belongs_to :user
end

I can now access the preferences of a user:

@u = User.first
@u.preference_set => #<PreferenceSet...>
@u.preference_set.play_sounds => true

But this fails if a preference set is not already created, since @u.preference_set will be returning nil, and I'll be calling play_sounds on nil.

What I want to archive is that User.preference_set always returns a PreferenceSet instance. I've tried defining it like this:

class User < ..
   has_one :preference_set

   def preference_set
     preference_set || build_preference_set
   end
end

This is causing a 'Stack level too deep', since it is calling itself recursively.

My question is this:

How can I ensure that @user.preference_set returns either the corresponding preference_set-record or, if none exists, builds a new one?

I know I could just rename my association (eg. preference_set_real) and avoid recursive calls this way, but for the sake of simplicity in my app, I'd like to keep the naming.

Thanks!

解决方案

Well the best way to do this is to create the associated record when you create the primary one:

class User < ActiveRecord::Base
   has_one       :preference_set, :autosave => true
   before_create :build_preference_set
end

That will set it up so whenever a User is created, so is a PreferenceSet. If you need to initialise the the associated record with arguments, then call a different method in before_create which calls build_preference_set(:my_options => "here") and then returns true.

You can then just normalise all existing records by iterating over any that don't have a PreferenceSet and building one by calling #create_preference_set.

If you want to only create the PreferenceSet when it is absolutely needed, then you can do something like:

class User < ActiveRecord::Base
   has_one :preference_set

   def preference_set_with_initialize
     preference_set_without_initialize || build_preference_set
   end

   alias_method_chain :preference_set, :initialize
end

这篇关于扶手:创建关联,如果没有被发现,避免零误差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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