Проблема с has_many :through и field_for
-
12-09-2019 - |
Вопрос
У меня довольно простая ассоциация:
# user.rb
class User < ActiveRecord::Base
has_many :services, :through => :subscriptions
has_many :subscriptions, :accessible => true
accepts_nested_attributes_for :subscriptions
end
# service.rb
class Service < ActiveRecord::Base
has_many :users, :through => :subscriptions
has_many :subscriptions
end
# subscription.rb
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :service
end
В подписке также есть логический столбец «уведомление», который мне нужно настроить индивидуально, поэтому я изучил API, последовал примеру и придумал для своей формы такой код:
- if current_user.subscriptions.length > 0
%fieldset#subscriptions
%legend Abonnements
%table
%tr
%th.name
%th.notification Notifications?
- for subscription in current_user.subscriptions do
%tr
- f.fields_for :subscriptions, subscription do |s|
%td=subscription.service.name
%td= s.check_box :notification
Но когда я сохраняю форму, все связанные подписки уничтожаются.Принимая во внимание, что когда я устанавливаю флажок, он не будет удален, но флажок тоже не сохраняется.Кто-нибудь знает, что я делаю неправильно?
Решение
После почти двухчасовых попыток я наконец-то заработал.Небольшого изменения в вашем коде было бы достаточно:
# _form.html.haml
# […]
- if current_user.subscriptions.length > 0
%fieldset#subscriptions
%legend Abonnements
%table
%tr
%th.name
%th.notification Notifications?
- f.fields_for :subscriptions do |sub|
%tr
%td= sub.object.service.name
%td
= sub.check_box :notification
= hidden_field_tag "user[service_ids][]", sub.object.service.id
# […]
Потому что params[:user][:service_ids]
был пуст, он удалил всю ассоциацию.
Другие советы
Вы не отправляете никаких подписок с помощью формы.Если не установить этот флажок, вам нечего будет отправлять для этой подписки, поэтому подписки уничтожаются функцией вложенных атрибутов.Попробуйте ввести скрытое поле с идентификатором службы подписки.
Я считаю, что вы также неправильно настраиваете форму для вложенных атрибутов.Попробуй это:
- if current_user.subscriptions.length > 0
%fieldset#subscriptions
%legend Abonnements
%table
%tr
%th.name
%th.notification Notifications?
- f.fields_for :subscriptions do |sub|
%tr
%td= sub.object.service.name
%td
= sub.check_box :notification
= sub.hidden_field :service_id