How to work with tests and fixtures in a bank that contains foreign key constraints in Rails?

Asked

Viewed 176 times

4

I am using Rubyonrails 4.1 and Postgresql database and use the Gem Foreigner to create foreign key restrictions in the bank. It turns out that this makes some tasks with fixtures.

When I try to run a test:

spring rake test

I usually have mistakes like that:

ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR:  update or delete on table "TABELA1" violates foreign key constraint "TABELA2_TABELA1_id_fk" on table "TABELA2"
DETAIL:  Key (id)=(980190962) is still referenced from table "TABELA2".
: DELETE FROM "TABELA1"

I can only run my tests because I recreate the bank before I spin them:

RAILS_ENV=test spring rake db:reset && spring rake test

I can’t use it either rake db:fixture:load to upgrade the fixtures to the development bank, gives the same error.

Change the order of fixtures in the file test_helper.rb was not enough.

Does anyone know how I can fix this? I did a lot of research on web and I couldn’t find a solution.

  • 1

    I have no knowledge of Rails, but might that help you (Foreign key support)? http://edgeguides.rubyonrails.org/4_2_release_notes.html

  • @gmsantos Interesting... The version 4.2 (still in Beta) will support Foreign Keys natively (today I use a Gem). But the link says nothing about fixtures and testing, we may no longer have this problem in the future. I will research more on... Thanks! = ) (I would still like a solution for the version 4.1)

3 answers

1

I am the original author of the question, and I have finally managed to solve this problem definitively.

The truth is that Rails tries to disable triggers which verify foreign key references before the setup the execution of the tests, when the basis is cleaned and the fixtures are reinserted into the base. After the setup, but before the tests are carried out, the triggers check are rehabilitated.

It turns out, for security reasons, Postgres only allows superuser users to disable these triggers. (Do not confuse the Linux superuser with the Postgres superuser. These are two different things! ). If you are logged in as a "common" user, the triggers shall remain qualified and setup will fail.


Solution

Thus, the solution is relatively simple. Just make your user a superuser in Postgres:

ALTER ROLE meuusuario SUPERUSER;

And automatically everything will work as it should.

1

A possible alternative solution is: instead of fixtures, work with factory_girl. And for cleaning the bank between tests, the Database Cleaner.

  • 1

    If it is not an answer, it is better to post as a comment. I made an edition to remove the meta-text, but I suggest a check on the guide [Answer].

  • I was in doubt whether to post as a comment or response. As it is an alternative solution I thought it could be useful as a possible answer.

1

See the error:

Foreignkeyviolation: ERROR: update or delete on table "TABELA1" violates Foreign key Constraint "Table2_table_id_fk" on table "TABELA2" DETAIL: Key (id)=(980190962) is still referenced from table "TABELA2".

You cannot delete a record from table 1 without first removing the reference from table 2. So, in this case, delete all references before deleting the record.

Also, see the documentation of Postgresql.

You could create the reference with ON DELETE CASCADE. Therefore, when deleting the record from Table 1, the references in Table 2 would be deleted automatically. There are other options that might be interesting in your case like:

  • RESTRICT
  • NO ACTION
  • CASCADE
  • SET NULL
  • SET DEFAULT

Browser other questions tagged

You are not signed in. Login or sign up in order to post.