Anatoliy Lysenko
2010-Nov-24 10:01 UTC
Surprise in (delete_all | clear | destroy_all) on association
Hi,
I was very surprised by difference of delete_all on association vs
model(delegated to relation).
Given TaskFilter.has_many(:qualifiers,
:class_name=>''TaskFilterQualifier'')
TaskFilter.delete_all => one DELETE statement
Without :dependent option on "qualifiers" association
TaskFilter.first.qualifiers.delete_all =>
SELECT `task_filter_qualifiers`.* FROM `task_filter_qualifiers` WHERE
(`task_filter_qualifiers`.task_filter_id = 1)
BEGIN
UPDATE `task_filter_qualifiers` SET `task_filter_id` = NULL WHERE
`task_filter_qualifiers`.`task_filter_id` = 1 AND
`task_filter_qualifiers`.`id` IN (90, 91)
COMMIT
Why UPDATE, not DELETE ?
With :dependent => :destroy
TaskFilter.first.qualifiers.delete_all =>
TaskFilter Load (0.9ms) SELECT `task_filters`.* FROM `task_filters` LIMIT
1
TaskFilterQualifier Load (0.9ms) SELECT `task_filter_qualifiers`.* FROM
`task_filter_qualifiers` WHERE (`task_filter_qualifiers`.task_filter_id = 1)
SQL (0.2ms) BEGIN
AREL (6.6ms) DELETE FROM `task_filter_qualifiers` WHERE
(`task_filter_qualifiers`.`id` = 92)
TaskFilter Load (6.4ms) SELECT `task_filters`.* FROM `task_filters` WHERE
(`task_filters`.`id` = 1) LIMIT 1
AREL (0.6ms) UPDATE `task_filters` SET `updated_at` = ''2010-11-24
09:28:03'' WHERE (`task_filters`.`id` = 1)
AREL (2.6ms) DELETE FROM `task_filter_qualifiers` WHERE
(`task_filter_qualifiers`.`id` = 93)
TaskFilter Load (8.2ms) SELECT `task_filters`.* FROM `task_filters` WHERE
(`task_filters`.`id` = 1) LIMIT 1
AREL (1.7ms) UPDATE `task_filters` SET `updated_at` = ''2010-11-24
09:28:03'' WHERE (`task_filters`.`id` = 1)
SQL (53.5ms) COMMIT
Note that I have :touch option, so sql below is produced by :touch callback
TaskFilter Load (6.4ms) SELECT `task_filters`.* FROM `task_filters` WHERE
(`task_filters`.`id` = 1) LIMIT 1
AREL (0.6ms) UPDATE `task_filters` SET `updated_at` = ''2010-11-24
09:28:03'' WHERE (`task_filters`.`id` = 1)
That is nightmare, I expect delete_all to be fast sql query, but instead I
have:
* all associated objects loaded
* each object was destroyed, with many callbacks and DELETE queries
delete_all, clear, destroy_all respect :dependent option, but why ?
If association hasn''t :dependent option, then delete_all is duplicate
of
clear
if association has :dependent=> :destroy option, then delete_all, clear are
duplicates of destroy_all
delete_all work fine on relation so,
TaskFilter.first.qualifiers.scoped.delete_all will work fine:
TaskFilter Load (1.3ms) SELECT `task_filters`.* FROM `task_filters` LIMIT
1
AREL (71.7ms) DELETE FROM `task_filter_qualifiers` WHERE
(`task_filter_qualifiers`.task_filter_id = 1)
Is this all intentional behavior ?
Maybe this ticket is related
https://rails.lighthouseapp.com/projects/8994/tickets/5196-delete_allnullify-in-associations-does-uneeded-queries
Thanks,
Anatoliy Lysenko
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.
