Эта опция существует в ассоциации has_many
, и она не задокументирована, но добрые люди из сообщества Rails предоставляют информацию о ней ниже в разделе комментариев. Так что, возможно, вы даже не знаете об этом варианте. И это здорово!
Но для тех, кто использует его в проекте или рассматривает возможность использования, напишу пару примеров, почему лучше этого не делать.
Предположим, у нас есть модели:
Выглядит чисто и аккуратно, но:
company = Company.first user = User.first # You'll see the raised error if you run: company.users = [] company.users.destroy(user) # No error but company doesn't have an association with the user anymore: company.users.first.destroy user.destroy
Еще хуже это работает с опцией through
:
project = Project.first user = User.first # You'll see the raised error if you run: project.users = [] project.users.destroy(user) # No error: project.tasks = [] project.tasks.first.destroy Task.find(task_id).destroy project.users.first.destroy User.find(user_id).destroy
Кстати, вы можете насладиться спором о after_remove
обратном вызове в обсуждении в репозитории Rails.
И если вы думаете, что after_destroy
callback решит ваши проблемы, извините, что разочаровал вас, но будет обратная ситуация: все случаи будут работать, кроме project.users = []
.
Поэтому я думаю, что это одна из многих причин избегать ада обратного вызова.