Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Foreign Key violation deleting has_many relationships with dependent destroy

I have a simple has_many relationship in a Rails 4.2 model:

class Owner < ActiveRecord::Base
  has_many :nested_things, :inverse_of => :owner, :class_name => "Nested::Thing", :dependent => :destroy
end

class Nested::Thing < ActiveRecord::Base
  belongs_to :owner, :inverse_of=>:nested_things
end

The models are considerably more complicated than this, with many other relationships.

When somebody tried to delete an Owner today, it failed, because there is a foreign key on the nested_things table:

> psql annoying_problem

psql (9.5.3)
Type "help" for help.

annoying_problem=# \d+ nested_things
                                                            Table "public.nested_things"
      Column      |            Type             |                           Modifiers                            | Storage  | Stats target | Description 
------------------+-----------------------------+----------------------------------------------------------------+----------+--------------+-------------
 id               | integer                     | not null default nextval('nested_things_id_seq'::regclass)     | plain    |              | 
 owner_id         | integer                     |                                                                | plain    |              | 

 Indexes:
    "nested_things_pkey" PRIMARY KEY, btree (id)
    "ix_nested_things_on_owner_id" btree (owner_id)
Foreign-key constraints:
    "nested_things_owner_id_fk" FOREIGN KEY (owner_id) REFERENCES owners(id)

When the owner is deleted, its a time consuming process - locally this particular record generated a 109,000 line log file of all the SQL executed. However, the nested_things relationship causes the entire operation to abort because a foreign key check fails.

Here is what seems to be the relevant part of the log file:

> grep -n nested_things delete-owner.txt 

....

109762: SQL (1.1ms)  DELETE FROM "nested_things" WHERE "nested_things"."id" = $1  [["id", 8665]]

109836: ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: 
        ERROR:  update or delete on table "owners" violates foreign key 
        constraint "nested_things_owner_id_fk" on table "nested_things"

109837: DETAIL:  Key (id)=(6343) is still referenced from table "nested_things".

There is only one nested_things entry for this owner. What can cause a :dependent => :destroy relationship in Rails, to delete the dependent relationship, but fail the foreign key check?

like image 998
John Naegle Avatar asked Nov 25 '25 17:11

John Naegle


1 Answers

Turns out the answer was a default scope on the has_many relationships that wasn't accounted for in the destroy.

like image 196
John Naegle Avatar answered Nov 27 '25 12:11

John Naegle