加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Rails:如果没有找到则创建关联,以避免nil错误

发布时间:2020-12-16 19:28:05 所属栏目:百科 来源:网络整理
导读:我有一个应用程序,我的用户可以拥有一组首选项.两者都存储为ActiveRecord模型,如下所示: class User AR::Base has_one :preference_setendclass PreferenceSet AR::Base belongs_to :userend 我现在可以访问用户的偏好: @u = User.first@u.preference_set
我有一个应用程序,我的用户可以拥有一组首选项.两者都存储为ActiveRecord模型,如下所示:
class User < AR::Base
   has_one :preference_set
end

class PreferenceSet < AR::Base
   belongs_to :user
end

我现在可以访问用户的偏好:

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

但是,如果尚未创建偏好设置,则会失败,因为@ u.preference_set将返回为零,我将以nil为单位调用play_sounds.

我想要归档的是User.preference_set总是返回一个PreferenceSet实例.我试过这样定义它:

class User < ..
   has_one :preference_set

   def preference_set
     preference_set || build_preference_set
   end
end

这是因为它是递归调用的,因此导致“堆栈级别太深”.

我的问题是这样的:

如何确保@ user.preference_set返回相应的preference_set-record,如果不存在,建立一个新的?

我知道我可以重命名我的关联(例如,preference_set_real),并避免这种递归调用,但是为了简化我的应用程序,我想保留命名.

谢谢!

解决方法

那么这样做的最好方法是在创建主要记录时创建关联的记录:
class User < ActiveRecord::Base
   has_one       :preference_set,:autosave => true
   before_create :build_preference_set
end

这将设置它,所以每当创建一个用户,PreferenceSet也是如此.如果需要使用参数初始化相关联的记录,则在调用build_preference_set(:my_options =>“here”)的before_create中调用另一种方法,然后返回true.

然后,您可以通过迭代任何没有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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读