问题描述
我有一个应用程序,我的用户可以拥有一套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记录或者,如果不存在,建立一个新的
我知道我可以只重命名我的协会(例如, preference_set_real
),并避免递归调用此方法,但对于简单起见,在我的应用程序的缘故,我倒是想保持命名。
谢谢!
那么做到这一点的最好办法是,当你创建创建相关记录主之一:
类用户的LT;的ActiveRecord :: Base的
HAS_ONE:preference_set,:自动保存=>真正
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
这篇关于扶手:创建关联,如果没有被发现,避免零误差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!