I am having an issue managing a has_many :through association using a form. What I DON'T want to do is edit the attributes of the associated model of which there is a plethora of information out there, rather, I want to manage the association ONLY. I understand I could do this by manipulating the form parameters passed to my action and build the relationships manually, but I would prefer to go the Rails way, if that is possible.
One interesting thing about my case is that this has_many :through association is actually on a Model which I am already saving using accepts_nested_attributes_for
Here are my models: Goals, Milestones and Programs.
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
Now in my Goal edit view, I need to be able to add and remove milestones, and for those milestones I need to be able to add and remove program associations. This is the code for my form.
<%= 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 %>
In my controller, I have
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
This form needs to be like a worksheet where you can make changes and only save your changes once you click save at the end, so I don't believe gems such as cocoon or nested_forms will help.
My code works perfectly so far for managing my Goals associated Milestones and their attributes. But now I want to be able to manage the list of Programs associated to those Milestones.
I have tried using accepts_nested_attributes_for but that is not exactly what I want because I don't care to edit the nested attributes of the model, the Program attributes are to remain static.
I thought I might be able to have something like this in my form for each program to build the associations:
<input type="hidden" name="goal[milestones_attributes][1][program_ids][1]" >
But that doesn't work either (of course I've added :program_ids to my white-listed parameters). Is there a magic rails method I need to add to my controller?
What am I missing here?
Thanks in advance!