Rails | 2月 23rd, 2010
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 を呼ぶかなぁ




