Удалить / уничтожить запись на join_table с помощью has_many через - PullRequest
0 голосов
/ 11 октября 2019

Я отображаю набор флажков и хочу удалить все Privilege из User.

  • Когда я отмечаю один из флажков, создается запись.
  • Когда я снимаю флажок с одного из флажков, запись удаляется.

Я обыскал все связанные вопросы, но, к сожалению, ни один из них не работает.

Rails 5.2.3

Пользователь

has_many :user_privileges, class_name: 'UserPrivileges'
has_many :privileges, through: :user_privileges

Привилегия

has_many :user_privileges, class_name: 'UserPrivileges'
has_many :users, through: :user_privileges

UserPrivileges

belongs_to :user
belongs_to :privilege

Проблема возникает, когда я хочу удалить (снять флажок) привилегированную запись last этого пользователя в join_table .

Запись все еще там, и нет никакого способа удалить / уничтожить эту конкретную запись.

Моя интуиция напоминает обратные вызовы, я пробовал разные способы использования dependent, но последняя запись все еще там.

Любые советы приветствуются.

Спасибо

1 Ответ

0 голосов
/ 11 октября 2019

Если вы хотите удалить запись из таблицы присоединения, вам нужно добавить отношение dependent: :destroy к has_many :through.

# privilege.rb
has_many :user_privileges, class_name: 'UserPrivileges'
has_many :users, through: :user_privileges, dependent: :destroy

См. Что удаляется? in API docs :

Здесь есть потенциальная ловушка: has_and_belongs_to_many и has_many: через ассоциации есть записи в таблицах соединений, а также связанные записи. Поэтому, когда мы вызываем один из этих методов удаления, что именно должно быть удалено?

Ответ заключается в том, что предполагается, что удаление в ассоциации связано с удалением связи между владельцем и связанным объектом (ами),а не обязательно сами связанные объекты. Таким образом, при использовании has_and_belongs_to_many и has_many: through записи объединения будут удалены, а связанные записи - нет.

Для запуска обратного вызова dependent: :destroy необходимо использовать destroy или destroy_allметод при удалении записи привилегии.

См. Удалить или уничтожить? в API документы :

Для has_many, destroy и destroy_all будетвсегда вызывайте метод уничтожения удаляемых записей, чтобы выполнялись обратные вызовы. Однако delete и delete_all будут выполнять удаление в соответствии со стратегией, заданной параметром: зависимый, или, если параметр не указан, он будет следовать стратегии по умолчанию. Стратегия по умолчанию состоит в том, чтобы ничего не делать (оставить внешние ключи с установленными родительскими идентификаторами), за исключением has_many: through, где стратегией по умолчанию является delete_all (удалить записи объединения, без выполнения их обратных вызовов).

...