Ruby on Rails deleting fixtures with foreign keys

喜你入骨 提交于 2019-12-03 14:58:52
liverwust

I encountered a similar problem, but I use PostgreSQL. I am posting my solution with the hope that an analogous solution exists for Firebird (which I have not personally used).

As you mentioned, when Rails executes the test suite, it starts by deleting all of the data in the database tables. This is tricky in the presence of foreign key constraints. In theory, one way to handle these constraints would be to figure out an appropriate order in which to delete records.

However, at least for PostgreSQL, Rails actually sidesteps the issue by temporarily disabling the triggers which would otherwise prevent violation of these foreign key constraints. It does this with the following (probably vendor-specific) pair of SQL commands, executed before and after the DELETE commands:

ALTER TABLE tablename DISABLE TRIGGER ALL
ALTER TABLE tablename ENABLE TRIGGER ALL

There's a catch: only a superuser role (where "role" basically means "user" in this context) can execute these commands. Effectively, Rails can't run tests unless it is using a PostgreSQL role with the superuser privilege. Maybe Firebird has superusers, too?

Side note for PostgreSQL users with this problem:

To grant superuser to a user (only do this on your test or development database)

Run this SQL statement: ALTER USER myuser WITH SUPERUSER;

This is the error message that appears as of Rails 4.2.4 when attempting to test without superuser privilege:

ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "tablename" violates foreign key constraint

In a future version of Rails, this more specific error message will be shown:

WARNING: Rails was not able to disable referential integrity. This is most likely caused due to missing permissions. Rails needs superuser privileges to disable referential integrity.

See rails/rails commit 72c1557 and PR #17726 for more details.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!