fields_for Anidado-doble HABTM
-
18-09-2019 - |
Pregunta
interesante segmento de código que no puedo ir a trabajar. Tengo los siguientes modelos / relaciones (código innecesario excluido)
class Service < ActiveRecord::Base
belongs_to :service_category, :foreign_key => "cats_uid_fk"
belongs_to :service_type, :foreign_key => "types_uid_fk"
has_and_belongs_to_many :service_subtypes, :join_table => "services_to_service_subs"
belongs_to :service_request, :foreign_key => "audits_uid_fk"
accepts_nested_attributes_for :service_subtypes
end
class ServiceSubtype < ActiveRecord::Base
belongs_to :service_types, :foreign_key => "types_uid_fk"
has_and_belongs_to_many :services, :join_table => "services_to_service_subs"
end
La forma de mostrar toda esta información:
<% form_for(@request, :url => { :action => :create }) do |form| %>
<table>
...other data...
<% form.fields_for :services do |fields| %>
<%= fields.hidden_field :cats_uid_fk %>
<%= fields.hidden_field :types_uid_fk %>
<% fields.fields_for :service_subtypes do |subtype| %>
<%= subtype.hidden_field :id %>
<% end %>
<% end %>
<p>
<%= form.submit "Create", :class=>"hargray" %>
</p>
<% end %>
Y el controlador para manejar la confirmación:
def create
logger.debug params[:service_request].inspect
@request = ServiceRequest.new(params[:service_request])
if session[:cus_id]
@request.customer = Customer.find session[:cus_id]
end
begin
@request.save!
flash[:notice] = "Information submitted successfully. You will be contacted by a customer service representative regarding the services you selected."
redirect_to :controller => "customer", :action => "index"
rescue Exception => exc
flash[:notice] = "#{ format_validations(@request) } - #{exc.message}"
render :action => "new"
end
end
El HTML se ve limpio:
<input id="service_request_services_attributes_0_cats_uid_fk" name="service_request[services_attributes][0][cats_uid_fk]" type="hidden" value="1" />
<input id="service_request_services_attributes_0_types_uid_fk" name="service_request[services_attributes][0][types_uid_fk]" type="hidden" value="1" />
<input id="service_request_services_attributes_0_service_subtypes_attributes_0_id" name="service_request[services_attributes][0][service_subtypes_attributes][0][id]" type="hidden" value="2" />
<input id="service_request_services_attributes_0_service_subtypes_attributes_0_id" name="service_request[services_attributes][0][service_subtypes_attributes][0][id]" type="hidden" value="2" />
<input id="service_request_services_attributes_0_service_subtypes_attributes_1_id" name="service_request[services_attributes][0][service_subtypes_attributes][1][id]" type="hidden" value="4" />
<input id="service_request_services_attributes_0_service_subtypes_attributes_1_id" name="service_request[services_attributes][0][service_subtypes_attributes][1][id]" type="hidden" value="4" />
Los parámetros presentados este aspecto:
{
...other data...
"services_attributes"=> {
"0"=> {
"types_uid_fk"=>"1",
"service_subtypes_attributes"=> {
"0"=>{"id"=>"1"},
"1"=>{"id"=>"2"},
"2"=>{"id"=>"3"}
},
"cats_uid_fk"=>"1"
}
}
}
regrese "método no definido 'service_subtype' para #" error y la única tabla no actualizada es la tabla de unión entre los modelos HABTM. ¿Alguna idea de cómo resolver esto o lo que está sucediendo detrás de las escenas? No estoy seguro de entender la "magia" sucediendo detrás de este procedimiento para ver su funcionamiento. Parece que la mayoría dice que HABTM no funciona con atributos anidados. Parece ser el caso. arounds de trabajo?
Solución 2
Se han encontrado que el error, se encontraba en mis anuncios publicitarios. En cualquier caso, los fields_for: subtipos todavía no estaba generando los parámetros adecuados para la magia de atributos anidados para recoger en lo que yo estaba tratando de hacer
.Lo que termino con es:
new.erb
<% form.fields_for :services do |fields| %>
<%= fields.hidden_field :wsi_web_serv_cats_uid_fk %>
<%= fields.hidden_field :wsi_web_serv_types_uid_fk %>
<%= fields.hidden_field :service_subs_hash %>
<% end %>
service.rb
def service_subs_hash
self.service_subtype_ids.join(", ")
end
def service_subs_hash=(ids)
self.service_subtype_ids = ids.split(",")
end
Esto es un poco hacker que siento y no estoy seguro de que estoy totalmente satisfecho con ella como la respuesta, pero pone una lista separada por comas en mi campo oculto que puedo analizar a service_subtype_ids nuevo en enviar.
Si alguien sabe cómo hacerlo sin este parámetro virtual adicional, me gustaría saber.
Gracias por la ayuda.
Otros consejos
Asumiendo que esto no es un error de copiar y pegar en el modelo de servicio, que podría ser el origen del problema.
accepts_nested_attributes_for :services_subtypes
En caso de ser
accepts_nested_attributes_for :service_subtypes
Los primeros argumentos para accepts_nested_attributes_for deben ser una asociación tal como se define por un has_many, has_and_belongs_to_many o belongs_to comunicado.
Su segundo problema menor alrededor del doble de generación del campo oculto proviene de su inserción en la sección fields_for. fields_for incluye automáticamente un campo oculto para la Identificación. Por lo que es seguro retirar la línea de campo oculto desde el siguiente bloque.
<% fields.fields_for :service_subtypes do |subtype| %>
<%= subtype.hidden_field :id %>
<% end %>