Description
It would appear that executing rebuild!
on a scoped collection empties the whole table before rebuilding the few selected elements.
In our case, the model is called BusinessUnit.
When you run BusinessUnit.where(id: [1, 2]).each { |bu| bu.rebuild! }
, the following SQL queries are executed (amongst the INSERT queries):
DELETE FROM "business_unit_hierarchies" WHERE descendant_id IN (SELECT DISTINCT descendant_id FROM (SELECT descendant_id FROM "business_unit_hierarchies" WHERE ancestor_id = 2 OR descendant_id = 2) AS x)
DELETE FROM "business_unit_hierarchies" WHERE descendant_id IN (SELECT DISTINCT descendant_id FROM (SELECT descendant_id FROM "business_unit_hierarchies" WHERE ancestor_id = 1 OR descendant_id = 1) AS x)
When you run BusinessUnit.where(id: [1, 2]).rebuild!
, the following SQL queries are executed (again, amongst the INSERT queries):
DELETE FROM "business_unit_hierarchies"
DELETE FROM "business_unit_hierarchies" WHERE descendant_id IN (SELECT DISTINCT descendant_id FROM (SELECT descendant_id FROM "business_unit_hierarchies" WHERE ancestor_id = 2 OR descendant_id = 2) AS x)
DELETE FROM "business_unit_hierarchies" WHERE descendant_id IN (SELECT DISTINCT descendant_id FROM (SELECT descendant_id FROM "business_unit_hierarchies" WHERE ancestor_id = 1 OR descendant_id = 1) AS x)
You will notice the extraneous DELETE FROM "business_unit_hierarchies"
, which completely empties the table before rebuilding only the two selected BusinessUnits.
We unfortunately experienced this problem in production, but were quickly able to recover by doing a full BusinessUnit.rebuild!
. However, I think it would be nice to fix this, to avoid the same situation from happening to another unfortunate soul.