简体   繁体   English

Rails / ActiveRecord:has_one,belongs_to和before_create

[英]Rails/ActiveRecord: has_one, belongs_to and before_create

I'm having trouble figuring out how best to model my data. 我在弄清楚如何最好地建模数据时遇到了麻烦。 I have the following two models in my Rails application: 我的Rails应用程序中有以下两个模型:

class Foo < ActiveRecord::Base
  belongs_to :active_bar, :class_name => 'Bar'
  accepts_nested_attributes_for :active_bar

  before_create do |f|
    f.active_bar.foo = f

    # Causes stack overflow!
    f.active_bar.save!
  end
end

class Bar < ActiveRecord::Base
  belongs_to :foo
end

test 'create with nested attributes' do
  f = Foo.create!(:name => 'foo-name', :active_bar_attributes => {:name => 'bar-name'})
  assert_equal 'foo-name', f.name
  assert_equal 'bar-name', f.active_bar.name
  assert_equal f, f.active_bar.foo

  f_id = f.to_param

  retrieved_f = Foo.find_by_id!(f_id)
  assert_equal retrieved_f, retrieved_f.active_bar.foo
end

What you probably think is strange is the reflexive belongs_to relationship I'm attempting to model. 什么,你可能觉得很奇怪是自反belongs_to关系,我试图建模。 My plan is that, eventually, Foo will have many instances of Bar while one instance will be considered "active". 我的计划是,最终, Foo将具有Bar许多实例,而一个实例将被视为“活动”。 Thus I'm using active_bar to refer to this active instance. 因此,我正在使用active_bar来引用此活动实例。 The problem with this code is that I need to set the foo property in Bar back to the parent Foo instance and I can't figure out the best place to do it (the save! call in before_create ends up being recursive and overflowing the stack) or even if this is the cleanest way to model this type of relationship. 这段代码的问题是,我需要将Barfoo属性设置回父Foo实例,并且我无法找出执行此操作的最佳位置( before_createsave!调用最终是递归的,并且溢出了堆栈),即使这是对这种类型的关系进行建模的最简洁的方法。

Essentially I'm attempting to model a user (equivalent to Foo ) who has multiple e-mail addresses (equivalent to Bar ) with one of the e-mail addresses marked as the user's primary address. 本质上,我正在尝试为具有多个电子邮件地址(相当于Bar )的用户(相当于Foo )建模,并将其中一个电子邮件地址标记为用户的主要地址。

Any advice? 有什么建议?

I'm just going to respond in terms of User and EmailAddress if that's okay with you ;) 如果您可以的话,我将就用户名和电子邮件地址做出回应;)

In your User model should really be has_many :email_addresses , has_one :active_email, :class_name => 'EmailAddress' and, as you correctly identified, accepts_nested_attributes_for :email_addresses 在您的用户模型中,实际上应该是has_many :email_addresseshas_one :active_email, :class_name => 'EmailAddress'并且如您所正确识别的那样, accepts_nested_attributes_for :email_addresses

The EmailAddress model should then, of course, have belongs_to :User . 然后,EmailAddress模型当然应该具有belongs_to :User

Aside from these, I think you are over-thinking things. 除了这些,我认为您正在考虑过多。 In the form to create a user, then, allow them to enter as many email addresses as they want and either have them put their "active" email first, or have some sort of toggle to denote which email address is their primary address. 然后,在创建用户的表单中,允许他们输入所需数量的电子邮件地址,或者让他们首先放置“活动”电子邮件,或者进行某种形式的切换以指示哪个电子邮件地址是其主要地址。

Edit: As far as the before_create statement, I think it only needs to be a simple validation that a primary email address has been given/marked (if it is necessary that they specify an email address in the first place). 编辑:就before_create语句而言,我认为只需要简单验证一下是否已指定/标记了主要电子邮件地址(如果有必要首先指定一个电子邮件地址)。

If this doesn't fulfull what functionality you need, please comment. 如果这不能满足您所需的功能,请发表评论。 I'll try and help more. 我会尽力帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM