I am trying to perform delete_all
on an ActiveRecord relation that has a lot of rows, and one level dependents.
When I used the destroy_all
, it was of course painfully slow, since it iterated over the entire relation.
When using delete_all
, I was unable to find a way to specify that rails should also delete (not destroy) its dependents.
This is what I know and tried:
- I have a
Member
model and aMessage
model. - In the member model I have
has_many :messages, inverse_of: :member, dependent: :destroy
- I thought that changing the above to
dependent: :delete_all
would delete all the dependents using one query (delete messages where member ID in [array of members to be deleted]) - it did not, and instead failed with a foreign key error. - I have already spent time in the appropriate Rails documentation pages (like this one) and in some related StackOverflow questions (like this one).
The solution I found so far is this:
# Define the Member collection we want to delete
members = Member.where comment: 'debug'
# Get all the IDs from it
ids = members.pluck :id
# Delete all the dependent Message objects first
Message.where(member_id: ids).delete_all
# Then delete the Members
members.delete_all
This is fast, and properly results in two delete queries.
My questions are:
- Wasn't the
dependent: :delete_all
definition supposed to do this for me? - Is there a more Rails-like way to do it? It feels like I am doing manually something that should have been taken care of by rails itself.