我在这两个模型之间的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