Mat*_*ias 13 activerecord ruby-on-rails has-one
我有一个应用程序,我的用户可以拥有一组首选项.两者都存储为ActiveRecord模型,如下所示:
class User < AR::Base
has_one :preference_set
end
class PreferenceSet < AR::Base
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)
我现在可以访问用户的首选项:
@u = User.first
@u.preference_set => #<PreferenceSet...>
@u.preference_set.play_sounds => true
Run Code Online (Sandbox Code Playgroud)
但是,这是否偏好设置尚未创建,因为@ u.preference_set将返回nil我将调用失败,play_sounds上nil.
我想归档的是User.preference_set总是返回一个PreferenceSet实例.我试过像这样定义它:
class User < ..
has_one :preference_set
def preference_set
preference_set || build_preference_set
end
end
Run Code Online (Sandbox Code Playgroud)
这导致a 'Stack level too deep',因为它以递归方式调用自身.
我的问题是:
如何确保@user.preference_set返回相应的preference_set-record,如果不存在则返回构建新的记录?
我知道我可以重命名我的关联(例如preference_set_real)并以这种方式避免递归调用,但为了我的应用程序的简单性,我想保留命名.
谢谢!
ino*_*tus 44
或者干脆
class User < ApplicationRecord
has_one :preference_set
def preference_set
super || build_preference_set
end
end
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为ActiveRecord定义了mixin中的关联方法.
Bo *_*nes 28
那么,最好的方法是在创建主要记录时创建关联记录:
class User < ActiveRecord::Base
has_one :preference_set, :autosave => true
before_create :build_preference_set
end
Run Code Online (Sandbox Code Playgroud)
这将设置它,所以无论什么时候User创建,所以是PreferenceSet.如果您需要初始化带参数的相关记录,然后调用不同的方法,before_create它调用build_preference_set(:my_options => "here"),然后返回true.
然后,您可以通过迭代任何没有a PreferenceSet并通过调用构建一个来对所有现有记录进行规范化#create_preference_set.
如果您只想创建PreferenceSet绝对需要的时间,那么您可以执行以下操作:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7784 次 |
| 最近记录: |