问题描述
我有一个问题,管理的has_many:通过联合使用的形式。我不希望做的是编辑相应的模型,其中有一个大量的信息在那里,说,我想只管理协会的属性。我知道我能做到这一点通过操纵传递到我的行动的形式参数和手动构建的关系,但我想preFER去Rails的方式,如果这是可能的。
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.
我的情况下,一个有趣的事情是,这的has_many:通过协会实际上是一个模式,我已经使用accepts_nested_attributes_for
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
现在,我的目标编辑视图,我需要能够添加和删除的里程碑,并为这些里程碑我需要能够添加和删除程序关联。这是code我的表。
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 %>
在我的控制器,我有
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
该表单需要像一个工作表,您可以进行更改,只有保存更改,一旦你点击保存到了最后,所以我不相信的宝石,如茧或nested_forms会有所帮助。
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.
我的code完美的作品至今管理我的目标相关的里程碑及其属性。但现在我希望能够管理相关的那些里程碑程序列表。
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.
我用accepts_nested_attributes_for试图但是这不正是我想要的,因为我不在乎编辑模型的嵌套属性,程序属性将保持不变。
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]" >
但是,这并不工作(当然,我说:program_ids到我的白名单参数)。是否有一个神奇的轨道的方法我需要添加到我的控制器?
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?
我是什么在这里失踪?
在此先感谢!
推荐答案
用人当<$c$c>has_many :通过 的关系,你需要通过 nested_attributes
通过不同的模式,像这样:
When employing a has_many :through
relationship, you need to pass the nested_attributes
through the different models, like this:
模型
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
控制器
#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
表格
#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 %>
我AP preciate这可能不是你在寻找什么,但TBH我没看过你所有的散文。我只收集你需要帮助传递 nested_attributes
通过的has_many:通过
相关
这篇关于轨道4嵌套属性和的has_many:通过associaton的形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!