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.