I have some model code that runs fine in development environment but
fails in the test environment.
In test, the code always fails at the same point with:
Mysql::Error: Duplicate entry '5-17' for key 'PRIMARY': INSERT INTO
`accessibilities_namespaces` (`accessibility_id`, `namespace_id`)
VALUES (17, 5)e[0m
accessibilities_namespaces is a join table for HABTM relationships.
My logging suggests that ActiveRecord tries to insert the same record
twice when run in test (but only in test!) which would explain the
above error. I am sure that the code does not try to create the same
record twice and in any case it runs fine in development mode.
I have tried running the code using 'script/console test' and it fails
here also. Though it does not fail when run in 'script/console
[development]'.
I suspect the problem does not lie with MySQL or ActiveRecord, but
something to do with the differences between running in development vs
test.
Initially it was failing when running the code from within a Cucumber
step definition. In this step definition, I am implementing a Given
step (in part) by calling a method of a model. This method is throwing
the error. In summary, the step definition is as follows:
Given ... do
user = User.create!(...)
member=Member.add_member_for_user(user) <----! error thrown by this
method
...
end
Having experienced the error within Cucumber, I then entered the same
code into 'script/console test' i.e.
If however I run the code in development or by using the development
console or as a standalone Ruby program which makes use of
ActiveRecord and my models, it runs fine.
The actual error that I receive when run in 'console test' is a
'Duplicate key' error when trying to insert into one of the join
(HABTM) tables. I stress this error is not raised when run in 'console
development' so I know that my code is not trying to insert duplicate
rows in this table.
The underlying MySQL table for this join table has a composite PRIMARY
KEY defined for the two foreign keys that make up the HABTM
relationship.
If I remove the PRIMARY KEY from the table definition, the code runs
fine in 'console test'.
What does 'console test' do differently to 'console development' to
cause this problem?
The error would suggest there is already a record with that composite key in the database. Have you tried looking at the db just before the error occurs (or after it for that matter) to see if there is already such a record?
When I remove the primary key from the join table the code runs
without error using console test but does create two records for each
pair of keys in the join table. The same code does not however create
pairs of records when run using console development. So something
strange is happening in the Rails test environment!
My googling suggests it's a bad idea to have composite primary keys on
join tables.