[英]Rails 4 nested attributes and has_many :through associaton in a form
I am having an issue managing a has_many :through association using a form. 我在管理has_many时遇到问题:通过使用表单进行关联。 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.
我理解我可以通过操作传递给我的操作的表单参数并手动构建关系来做到这一点,但我更愿意采用Rails方式,如果可能的话。
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 关于我的一个有趣的事情是,这个has_many:通过关联实际上是一个模型,我已经使用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. 此表单必须像工作表,您可以在其中进行更改,并且只在最后单击保存时保存更改,因此我不相信诸如cocoon或nested_forms之类的gem会有所帮助。
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. 我尝试过使用accepts_nested_attributes_for,但这并不是我想要的,因为我不关心编辑模型的嵌套属性,Program属性要保持静态。
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). 但这也不起作用(当然我已经添加了:program_ids到我列入白名单的参数)。 Is there a magic rails method I need to add to my controller?
我需要添加到控制器中的魔术轨道方法吗?
What am I missing here? 我在这里错过了什么?
Thanks in advance! 提前致谢!
When employing a has_many :through
relationship, you need to pass the nested_attributes
through the different models, like this: 使用
has_many :through
关系时,需要通过不同的模型传递nested_attributes
,如下所示:
Models 楷模
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
Controller 调节器
#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
Form 形成
#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 %>
I appreciate this might not be exactly what you're looking for, but tbh I didn't read all your prose. 我很欣赏这可能不是你想要的,但是我没有阅读你所有的散文。 I just gathered you needed help passing
nested_attributes
through a has_many :through
relationship 我刚刚收集了你需要帮助通过
has_many :through
关系传递nested_attributes
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.