Problema com has_many: through e fields_for
-
12-09-2019 - |
Pergunta
Eu tenho uma associação bastante básico:
# 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
A assinatura também tem uma coluna booleana "notificação", que eu preciso configurar individualmente, então eu olhei para o API , seguiu o exemplo e veio com este código para o meu formulário:
- 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
Mas quando eu guardar o formulário, todas as assinaturas associadas são destruídos. Considerando que, quando eu verificar a caixa de seleção não vai ser eliminado, , mas a caixa de seleção não é salvo seja . Alguém sabe o que estou fazendo de errado?
Solução
Depois de tentar em torno de quase 2 horas, eu finalmente tenho que trabalhar. Uma ligeira alteração ao seu código teria sido suficiente:
# _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
# […]
Porque params[:user][:service_ids]
estava vazio, apagado toda a associação.
Outras dicas
Você não está enviando nenhum assinaturas com o formulário. Sem clique na caixa, você não tem nada para enviar para essa assinatura, para as inscrições estão sendo dizimado pela funcionalidade atributos aninhada. Tente colocar em um campo escondido com ID de serviço da subscrição.
Eu acredito que você também está a configurar a forma de atributos aninhados incorretamente. Tente isto:
- 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