Офигенный баг AR колбеков

Илья • 27 мая 2009 г.

Сегодня потратил полтора часа, пытаясь починить проблему с before_destroy колбеком в одной из моделей. По какой-то причине Рельса удаляла одну из ассоциаций перед тем как вызвать before_destroy, который в свою очередь пытался работать с этой ассоциацией.

В итоге всё оказалось весьма банально. Каждая рельсовая ассоциация с параметром :dependent => :destroy добавляет в модель новый before_destroy колбек. Колбеки для модели Рельса никак не сортирует и запускает по правилу «первый добавился, первый выстрелил». Следовательно если ваши before_destroy прописаны в модели после ассоциаций с :dependent => :destroy, то и запустятся они после того как ассоциации будут удалены. В такие моменты я ненавижу Рельсы..

Так что сегодня выучил для себя новый урок: декларации before_destroy должны идти всегда перед ассоциациями, у которых установлен :dependent => :destroy.

То есть не так:

class Account < ActiveRecord::Base
  has_many :users, :dependent => :destroy
  before_destroy :do_something_funky_with_users
end

А вот так:

class Account < ActiveRecord::Base
  before_destroy :do_something_funky_with_users
  has_many :users, :dependent => :destroy 
end

2 комментария:

  1. ACheremukhin:

    Почему баг? Вроде обозначенное поведение.

  2. Илья Сабанин:

    Это баг, потому-что совершенно не очевидно, что перестановка строк модели может так отразится на колбеках. Напоминает игру в рулетку: повезло, не повезло.

    Правильно было бы всегда запускать рельсовые встроенные колбеки (сгенерированные :dependent => :destroy) после запуска пользовательских before_destroy, а не мешать их в общий винегрет.

Извините, но комментарии для этой статьи уже закрыты.