Rails + FactoryGirl + has_and_belongs_to_many =>重复输入错误

时间:2014-08-08 15:33:23

标签: ruby-on-rails-3 factory-bot has-and-belongs-to-many

我在这两个模型之间的join_table上遇到重复条目时遇到问题:

Journal < AR::Base
  has_and_belongs_to_many :journalists
  .....
end


Journalist < AR::Base
  has_and_belongs_to_many :journals
  .....
end
他们的工厂是:

  factory :journal do
    sequence(:name) { |n| "journal_#{n}" }
    address 'Address'
    website 'http://example.com'
    email { "#{name}@example.com" }

    after :build do |record, eval|
      unless record.journalists.any?
        record.journalists << build_list(:journalist, 1, journals: [record])
      end
    end
  end

  factory :journalist do
    sequence(:name) { |n| "journalist_#{n}" }
    email { "#{name}@example.com" }
  end

建筑记录不会产生任何问题。

但是此规范示例失败

it 'should work' do
  create(:journal)
end

ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry '1-1' for key 'index_journalists_journals_on_journalist_id_and_journal_id': INSERT INTO `journalists_journals` (`journal_id`, `journalist_id`) VALUES (1, 1)

看看RSpec Log,我看到了:

   (0.1ms)  BEGIN
   (0.2ms)  SAVEPOINT active_record_2
  SQL (0.4ms)  INSERT INTO `journals` (`address`, `created_at`, `email`, `fax`, `name`, `phone`, `updated_at`, `website`) VALUES ('Address', '2014-09-04 09:32:45', 'journal_1@example.com', NULL, 'journal_1', NULL, '2014-09-04 09:32:45', 'http://example.com')
  SQL (0.2ms)  INSERT INTO `journalists` (`created_at`, `email`, `name`, `phone`, `updated_at`) VALUES ('2014-09-04 09:32:45', 'journalist_1@example.com', 'journalist_1', NULL, '2014-09-04 09:32:45')
   (0.2ms)  INSERT INTO `journalists_journals` (`journalist_id`, `journal_id`) VALUES (1, 1)
   (0.9ms)  INSERT INTO `journalists_journals` (`journal_id`, `journalist_id`) VALUES (1, 1)
Mysql2::Error: Duplicate entry '1-1' for key 'index_journalists_journals_on_journalist_id_and_journal_id': INSERT INTO `journalists_journals` (`journal_id`, `journalist_id`) VALUES (1, 1)
   (0.5ms)  ROLLBACK TO SAVEPOINT active_record_2

它尝试两次插入habtm关系的记录。

我一直在努力解决这个问题几个小时,但除了将期刊工厂改为以外,我找不到解决方案:

  factory :journal do
    sequence(:name) { |n| "journal_#{n}" }
    address 'Address'
    website 'http://example.com'
    email { "#{name}@example.com" }

    after :build do |record, eval|
      unless record.journalists.any?
        record.journalists << build_list(:journalist, 1) #no backreference to this journal until the record is saved
      end
    end
  end

0 个答案:

没有答案