Wednesday 24 October 2007

Disable Foreign Key Check Under MySQL


Mysql::Error: #23000Cannot add or update a child row: a foreign key constraint fails
(`depot_development/line_items`,
CONSTRAINT `fk_items_product` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`)
ON DELETE CASCADE): INSERT INTO line_items (`quantity`, `product_id`, `id`,
`unit_price`) VALUES (1, 1, 1, 29.95)

OR

ActiveRecord::StatementInvalid: Mysql::Error:
Cannot delete or update a parent row: a foreign key constraint fails:
DELETE FROM line_items WHERE id = 1


If you've ever gotten the above error message from unit testing with Rails, this is what you gotta do.

Turn off constraints when fixtures are loaded to run unit tests by adding the following to the end of test_helper.rb:


class Fixtures
def delete_existing_fixtures_with_fk_checks_disabled
@connection.update "SET FOREIGN_KEY_CHECKS = 0"
delete_existing_fixtures_without_fk_checks_disabled
@connection.update "SET FOREIGN_KEY_CHECKS = 1"
end

def insert_fixtures_with_fk_checks_disabled
@connection.update "SET FOREIGN_KEY_CHECKS = 0"
insert_fixtures_without_fk_checks_disabled
@connection.update "SET FOREIGN_KEY_CHECKS = 1"
end

alias_method_chain :delete_existing_fixtures, :fk_checks_disabled unless method_defined?(:delete_existing_fixtures_without_fk_checks_disabled)
alias_method_chain :insert_fixtures, :fk_checks_disabled unless method_defined?(:insert_fixtures_without_fk_checks_disabled)
end


Read more about it here.

No comments: