简体   繁体   English

与has_many关系的Factory Girl错误

[英]Factory Girl error with has_many relationship

I have the following factories: 我有以下工厂:

Factory.define :email do |email|
  email.email {"infomcburney.cowan.com"}
end

Factory.define :lead do |lead|
  lead.emails {|emails| [emails.association(:email)]}
end

Which are modeling the following classes 以下是为以下类建模的

class Lead < ActiveRecord::Base
  has_many :emails
end

class Email < ActiveRecord::Base
  belongs_to :lead, :class_name => "Lead", :foreign_key => "lead_id"
end

When I run the this test through shoulda: 当我通过shoulda运行此测试时:

    should "capture emails" do
      lead = Factory.build(:lead)
      assert_equal(1, lead.emails.size)
    end

I get the following error: 我收到以下错误:

Factory::AttributeDefinitionError: Attribute already defined: emails Factory :: AttributeDefinitionError:已定义的属性:电子邮件

I am completely stuck on this, can anyone point me in the right direction. 我完全坚持这个,任何人都可以指出我正确的方向。 I am using factory_girl 1.3.2. 我正在使用factory_girl 1.3.2。

I would recommend against adding has_many relationship data to your factories. 我建议不要将has_many关系数据添加到工厂。 The reason for this is that your lead factory now depends on populating this association and it's adding more coupling and potentially some confusion down the road if the association changes. 这样做的原因是你的主要工厂现在依赖于填充这种关联,并且如果关联发生变化,它会增加更多的耦合并可能引起一些混乱。

If you want to test this relationship (and I recommend you do), there's a great gem called Shoulda that adds unit test macros to ensure that the relationships are setup right. 如果你想测试这种关系(我建议你这样做),有一个名为Shoulda的伟大的宝石,它增加了单元测试宏,以确保关系设置正确。 I haven't used it with the built in Rails Test::Unit, but an RSpec example would look something like: 我没有使用内置的Rails Test :: Unit,但RSpec示例看起来像:

describe Lead do
  it { should have_many(:emails) }
end

If you really want to test this relationship, you should do it in the spec. 如果你真的想测试这种关系,你应该在规范中做。 Remove the emails association from your lead factory and create a lead object and try to pass it a few email objects like so: 从您的潜在客户工厂中删除电子邮件关联并创建一个潜在客户对象并尝试传递一些电子邮件对象,如下所示:

lead = Factory.build(:lead)
2.times do { lead.emails << Factory.build(:email, :lead => lead) }

Then it should have a couple emails association with it. 然后它应该与它有几个电子邮件关联。 However, you should put some faith in ActiveRecord and just test things that are above and beyond what Rails is already doing for you. 但是,你应该对ActiveRecord有一些信心,只是测试一些超出Rails已经为你做的事情。 This is where Shoulda comes in. 这就是Shoulda的用武之地。

Another comment I have is on your Email belongs_to relationship. 我的另一个评论是你的电子邮件belongs_to关系。 Since you're just using the default conventions, rails will know what to do. 由于您只是使用默认约定,因此rails将知道该怎么做。

class Email < ActiveRecord::Base
  belongs_to :lead
end

This is an interesting article which could be helpful: 这是一篇有趣的文章,可能会有所帮助:

http://icelab.com.au/articles/factorygirl-and-has-many-associations/ http://icelab.com.au/articles/factorygirl-and-has-many-associations/

    FactoryGirl.define do
      factory :venue_with_gigs, :parent => :venue do
        after_create do |venue|
          FactoryGirl.create(:gig, :venue => venue)
        end
      end
    end

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

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