Problema con has_many: a través y campos_for
-
12-09-2019 - |
Pregunta
Tengo una asociación bastante básica:
# 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
La Suscripción también tiene una "notificación" de columna booleana que necesito configurar individualmente, así que miré el API, seguí el ejemplo y se me ocurrió este código para mi formulario:
- 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
Pero cuando guardo el formulario, todas las suscripciones asociadas se destruyen.Mientras que cuando marco la casilla de verificación no se eliminará, pero el checkbox tampoco se guarda.¿Alguien sabe qué estoy haciendo mal?
Solución
Después de probar todo por casi 2 horas, por fin tengo trabajo. Un ligero cambio en su código hubiera 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
# […]
Debido params[:user][:service_ids]
estaba vacía, se suprime toda la asociación.
Otros consejos
No estás enviando ninguna suscripción con el formulario.Sin hacer clic en la casilla de verificación, no tiene nada que enviar para esa suscripción, por lo que la funcionalidad de atributos anidados elimina las suscripciones.Intente colocar un campo oculto con la identificación del servicio de la suscripción.
Creo que también está configurando incorrectamente el formulario para atributos anidados.Prueba esto:
- 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