首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >让工厂中的两个关联共享另一个关联

让工厂中的两个关联共享另一个关联
EN

Stack Overflow用户
提问于 2012-01-11 21:31:31
回答 6查看 4.2K关注 0票数 20

我有这5个模型:卫报,学生,关系,RelationshipType和学校。在他们之间,我有这些联想

代码语言:javascript
复制
class Guardian < ActiveRecord::Base
  belongs_to :school
  has_many :relationships, :dependent => :destroy
  has_many :students, :through => :relationships
end

class Student < ActiveRecord::Base
  belongs_to :school
  has_many :relationships, :dependent => :destroy
  has_many :guardians, :through => :relationships
end

class Relationship < ActiveRecord::Base
  belongs_to :student
  belongs_to :guardian
  belongs_to :relationship_type
end

class School < ActiveRecord::Base
  has_many :guardians, :dependent => :destroy
  has_many :students, :dependent => :destroy
end

class RelationshipType < ActiveRecord::Base
  has_many :relationships
end

我想写一个定义关系的FactoryGirl。每段关系都必须有一个监护人和一个学生。这两个肯定是同一所学校的。卫报工厂与学校有联系,学生工厂也是如此。我一直无法让它们在同一所学校里建造。我得到了以下代码:

代码语言:javascript
复制
FactoryGirl.define do

  factory :relationship do
    association :guardian
    association :student, :school => self.guardian.school
    relationship_type RelationshipType.first
  end

end

当我尝试使用此工厂构建关系时,这会导致以下错误:

代码语言:javascript
复制
undefined method `school' for #<FactoryGirl::Declaration::Implicit:0x0000010098af98> (NoMethodError)

有没有办法做到我想要的,让监护人和学生属于同一所学校,而不必求助于已经创建的监护人和学生到工厂(这不是它的目的)?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-01-15 02:43:29

我认为这应该行得通:

代码语言:javascript
复制
FactoryGirl.define do
  factory :relationship do 
    association :guardian
    relationship_type RelationshipType.first
    after_build do |relationship|
      relationship.student = Factory(:student, :school => relationship.guardian.school)
    end
  end
end
票数 10
EN

Stack Overflow用户

发布于 2013-01-27 03:51:34

这个答案是谷歌上“工厂女孩分享协会”的第一个结果,来自santuxus的答案真的帮了我很大的忙:)

下面是最新版本的Factory Girl的语法更新,以防其他人偶然发现:

代码语言:javascript
复制
FactoryGirl.define do
  factory :relationship do
    guardian
    relationship_type RelationshipType.first

    after(:build) do |relationship|
      relationship.student = FactoryGirl.create(:student, school: relationship.guardian.school) unless relationship.student.present?
    end
  end
end

unless子句防止student在与FactoryGirl.create(:relationship, student: foo)一起传入工厂时被替换。

票数 11
EN

Stack Overflow用户

发布于 2015-10-06 00:47:42

有一种更清晰的方式来编写这种关联。从this github issue那里得到了答案。

代码语言:javascript
复制
FactoryGirl.define do
  factory :relationship do 
    association :guardian
    student { build(:student, school: relationship.guardian.school) }
    relationship_type RelationshipType.first
  end
end
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8820114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档