Shop has_many Items という状況のとき、とある shop が持っている items を、下記のように取ることが出来ます。それに対して、条件を設定することも出来ます。
>> @shop.items
=> [Item id:21 shop_id: 1, Item id: 22, shop_id: 1, ....]
>> @shop.item.find_all_by_category("CPU")
=> [Item id:23 shop_id: 1, Item id: 26, shop_id: 1, ....]
そこで、同様にとある Shop の Items を全部 delete_all にしようとしたのですが、DELETE されるのではなく、外部キーにNULLがセットされるという挙動になっています。
>> @shop.items.delete_all
とすると
Item Update (3.0ms) UPDATE `items` SET shop_id = NULL WHERE (shop_id = 1 AND id IN (22,23,24,25,26))
のようになります。
Rails の API を見ると
# File vendor/rails/activerecord/lib/active_record/base.rb, line 897
897: def delete_all(conditions = nil)
898: sql = "DELETE FROM #{quoted_table_name} "
899: add_conditions!(sql, conditions, scope(:find))
900: connection.delete(sql, "#{name} Delete all")
901: end
みたいになっているのですが、Dynamic Scopes はまた別のところで定義されているっぽいです。
>> @shop.items.destroy_all
としてみると、下記のように DELETE になりますが、SQL が発行されまくってるのでだめぽいです。そもそも destroy は、destroy をトリガーにしている各種処理をしてから DELETE が行われるので、そもそも delete とは意味合いが違うというので仕方ないです。
Item Destroy (3.0ms) DELETE FROM `items` WHERE WHERE id = 21
Item Destroy (3.0ms) DELETE FROM `items` WHERE WHERE id = 22
Item Destroy (3.0ms) DELETE FROM `items` WHERE WHERE id = 23
ふつうに Item.delete_all を呼ぶかなぁ