rails formularios anidados ruby-on-rails forms activerecord ruby-on-rails-4

ruby on rails - formularios - Rails 4 atributos anidados y has_many: a través de la asociación en una forma



formularios en rails (1)

Al emplear una relación has_many :through , debe pasar los nested_attributes través de los diferentes modelos, como este:

Modelos

class Goal < ActiveRecord::Base has_many :milestones, inverse_of: :goal, dependent: :destroy accepts_nested_attributes_for :milestones, :allow_destroy => true def self.build goal = self.new goal.milestones.build.milestone_programs.build_program end end class Milestone < ActiveRecord::Base belongs_to :goal, inverse_of: :milestones has_many :milestone_programs has_many :programs, through: :milestone_programs accepts_nested_attributes_for :milestone_programs end class MilestoneProgram < ActiveRecord::Base belongs_to :milestone belongs_to :program accepts_nested_attributes_for :program end class Program has_many :milestone_programs has_many :milestones, through: :milestone_programs end

Controlador

#app/controllers/goals_controller.rb def new @goal = Goal.build end def create @goal = Goal.new(goal_params) @goal.save end private def goal_params params.require(:goal).permit(milestones_attributes: [milestone_programs_attributes: [program_attributes:[]]]) end

Formar

#app/views/goals/new.html.erb <%= form_for @goal do |f| %> <%= f.fields_for :milestones do |m| %> <%= m.fields_for :milestone_programs do |mp| %> <%= mp.fields_for :program do |p| %> <%= p.text_field :name %> <% end %> <% end %> <% end %> <%= f.submit %> <% end %>

Aprecio que esto no sea exactamente lo que estás buscando, pero no leí toda tu prosa. Acabo de nested_attributes que necesitabas ayuda para pasar los nested_attributes través de una relación has_many :through

Tengo un problema al gestionar un has_many: a través de una asociación que utiliza un formulario. Lo que NO quiero hacer es editar los atributos del modelo asociado de los que hay una gran cantidad de información, más bien, quiero administrar la asociación ÚNICAMENTE. Entiendo que podría hacer esto manipulando los parámetros de formulario pasados ​​a mi acción y construir las relaciones manualmente, pero preferiría seguir el camino de Rieles, si eso es posible.

Una cosa interesante de mi caso es que este has_many: a través de la asociación está en realidad en un modelo que ya estoy guardando usando accepts_nested_attributes_for

Aquí están mis modelos: Metas, Hitos y Programas.

class Goal < ActiveRecord::Base has_many :milestones, inverse_of: :goal, dependent: :destroy accepts_nested_attributes_for :milestones, :allow_destroy => true end class Milestone < ActiveRecord::Base belongs_to :goal, inverse_of: :milestones has_many :milestone_programs has_many :programs, :through => :milestone_programs end class Program < ActiveRecord::Base end

Ahora, en mi vista de edición de objetivos, necesito poder agregar y quitar hitos, y para esos hitos necesito poder agregar y eliminar asociaciones de programas. Este es el código de mi formulario.

<%= form_for @goal do |f| %> <%= f.fields_for :milestones do |f_milestone| %> <%= f.hidden_field :id, :value => f.object.id %> <%= f.hidden_field :name, :value => f.object.name %> <a href="javascript:void(0)" class="milestone-remove">- remove</a> <ul> <%= f.fields_for :programs do |f_prog| %> <li> <%= f_prog.object.name %> <a href="javascript:void(0)" class="program-remove">- remove</a> </li> <% end %> </ul> <% end %> <%= f.submit ''Save'' %> <% end %>

En mi controlador, tengo

class GoalsController < ApplicationController # PATCH/PUT /goals/:id def update if @goal.update(goal_params) redirect_to @goal end end def goal_params params.require(:goal).permit(:name, :milestones_attributes => [ :id, :name, :_destroy ]) end end

Este formulario debe ser como una hoja de trabajo donde puede realizar cambios y solo guardar los cambios una vez que haga clic en guardar al final, por lo que no creo que las gemas como cocoon o nestted_forms ayuden.

Mi código funciona perfectamente hasta ahora para administrar mis objetivos asociados a los objetivos y sus atributos. Pero ahora quiero poder administrar la lista de Programas asociados a esos Hitos.

He intentado usar accepts_nested_attributes_for pero eso no es exactamente lo que quiero porque no me importa editar los atributos anidados del modelo, los atributos del programa deben permanecer estáticos.

Pensé que podría tener algo como esto en mi formulario para cada programa para construir las asociaciones:

<input type="hidden" name="goal[milestones_attributes][1][program_ids][1]" >

Pero eso tampoco funciona (por supuesto que he agregado: program_ids a mis parámetros listados en blanco). ¿Hay algún método de rieles mágicos que deba agregar a mi controlador?

¿Que me estoy perdiendo aqui?

¡Gracias por adelantado!