ruby-on-rails - FactoryGirl 和 RSpec : create a record with required nested_attributes for specs

标签 ruby-on-rails ruby rspec factory-bot

我有一个模型 contact,它 has_many :locations,通过: :relationships,以及 has_many :teams,通过: :contacts_teams

联系人必须拥有关联的团队位置才能通过验证。换句话说:新的联系人必须具有关联的relationship记录和关联的contacts_team记录。以下为型号:

#models/contact.rb
class Contact < ActiveRecord::Base
  has_many :contacts_teams
  has_many :teams, through: :contacts

  has_many :relationships, dependent: :destroy
  has_many :locations, through: :relationships

  accepts_nested_attributes_for :contacts_teams, allow_destroy: true

  # upon create, validate that at least one associated team and one associated location exist
  validate :at_least_one_contacts_team
  validate :at_least_one_relationship

  private

  def at_least_one_contacts_team
    return errors.add :base, "Must have at least one Team" unless contacts_teams.length > 0
  end

  def at_least_one_relationship
    return errors.add :base, "Must have at least one Location" unless relationships.length > 0
  end
end

#models/contacts_team.rb
class ContactsTeam < ActiveRecord::Base
  belongs_to :contact
  belongs_to :team
end

#models/team.rb
class Team < ActiveRecord::Base
  has_many :contacts_teams
  has_many :contacts, through: :contacts_teams
end

#models/relationship.rb
class Relationship < ActiveRecord::Base
  belongs_to :contact
  belongs_to :location
end

#models/location.rb
class Location < ActiveRecord::Base
  has_many :relationships
  has_many :contacts, through: :relationships
end

用于测试:使用 factory_girl我想创建一个能够成功创建 contact 记录的 contact 工厂。由于每个 contact 记录都需要关联的 contacts_team 记录和 relationship 记录:当我创建 contact 记录时,应该创建那些也是如此。同样:contacts_team 记录应具有与其关联的现有team,而relation 记录应具有现有location代码 > 它关联到。因此本质上它还应该创建一个位置和一个团队记录。

如何使用工厂创建联系人记录,从而实际上创建关联的 contacts_team 记录和 relationship 记录?

这是我目前的工厂:

FactoryGirl.define do
  factory :contact do
    first_name "Homer"
    last_name "Simpson"
    title "Nuclear Saftey Inspector"
  end
end

FactoryGirl.define do
  factory :contacts_team do
  end
end

FactoryGirl.define do
  factory :team do
    name "Safety Inspection Team"
  end
end

FactoryGirl.define do
  factory :relationship do
  end
end

FactoryGirl.define do
  factory :location do
    name "Safety Location"
  end
end

如果使用factory_girl很难/不可能做到这一点:我该如何使用直接rspec来做到这一点?问题是我无法创建 contacts_team 记录或 relationship 记录,因为它关联的 contact 尚不存在!而且我无法创建 contact 记录,因为关联的 contacts_team 记录或 relationship 记录尚不存在。看起来我被困住了,但必须有一种不马虎的方法来做到这一点。

最佳答案

我上周刚刚有类似的要求。

在你的工厂结束后,你可以调用下一个工厂,然后它们就会关联起来。例如:

/spec/factories/contacts.rb

FactoryGirl.define do

    factory :contact do |c|
        first_name "Homer"
        last_name "Simpson"
        title "Nuclear Saftey Inspector"

        # now, call the other two factories
        relationship
        contacts_team
    end


    factory :contacts_team do
        # call the team factory
        team
    end


    factory :relationship do
        # call the location factory
        location
    end


    # define the team and location factories...

end

现在,在/spec/controllers/contacts_controller_spec.rb

contact = FactoryGirl.create(:contact)

您可以使用 Factory Girl 来创建联系人,即使您只需要一个位置,因为所有内容都会立即生成。

替代方案(rspec)

不要“链接”你的工厂,而是在/spec/controllers/contacts_controller_spec.rb中

contact = FactoryGirl.create(:contact)
# use .create_list(model, number, parent) to make children of a specific parent
contacts_team = FactoryGirl.create_list(:contacts_team, 3, :contact => contact)
relationship = FactoryGirl.create_list(:relationship, 3, :contact => contact)
team = FactoryGirl.create_list(:team, 3, :contacts_team => contacts_team)
location = FactoryGirl.create_list(:location, 3, :relationship => relationship)

这将创建一个联系人,其中包含 3 个 contact_teams(包含 3 个团队)和 3 个关系(包含 3 个位置)

希望这可以帮助您找出正确的模式来制作测试数据:)

关于ruby-on-rails - FactoryGirl 和 RSpec : create a record with required nested_attributes for specs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36207578/

相关文章:

mysql - Rails where on 查询结果

ruby-on-rails - 正确转义反斜杠

ruby - 在数组上使用累加器映射

rspec - rspec 中的钩子(Hook)之前与 :all? 之前相同

php - 我是否在登录系统中使用 cookie 或 session 登录?

ruby-on-rails - Simple_form Bootstrap 样式内联表单无法正常工作

mysql - Rake:数据库迁移因预先存在的 mySQL 数据库而失败

ruby-on-rails - Rails before_save 方法无法执行 'else' block

ruby-on-rails - 如何测试 before_filter 与 Rails 中的 RSpec 是否正常工作

ruby-on-rails - 测试流程(交叉 Controller )的最佳方法是什么?