我有一个非常基本的Rails 4应用程序,并使用Cocoon的嵌套表单来管理has_many... :through
模型关联。
class Student < ActiveRecord::Base
has_many :evaluations
has_many :assessments, through: :evaluations
# ... etc
end
class Evaluation < ActiveRecord::Base
belongs_to :student
belongs_to :assessment
# ... etc
end
class Assessment < ActiveRecord::Base
has_many :evaluations
has_many :students, through: :evaluations
accepts_nested_attributes_for :evaluation, reject_if: :all_blank
# ... etc
end
当我在视图中使用Cocoon时,我想使用新的Assessment
视图预先填充所有Student
条记录,以便为每个记录创建新的Evaluation
。我不想在控制器端做一些hacky逻辑手动添加一些新记录,那么我将如何构建传入请求?使用Cocoon,我看到请求在id
将要去的空间中有一些数字(我已用下面的??
替换了这些数字)。
{"utf8"=>"✓", "authenticity_token"=>"whatever", "assessment"=>{"description"=>"quiz 3", "date(3i)"=>"24", "date(2i)"=>"10", "date(1i)"=>"2015", "assessments_attributes"=>{"??"=>{"student_id"=>"2", "grade" => "A"}, "??"=>{"student_id"=>"1", "grade" => "B"}, "??"=>{"student_id"=>"3", "grade"=>"C"}}, }}, "commit"=>"Create Assessment"}
我在Coccoon source code中看到这是以某种方式生成的,但我无法弄清楚它如何与Rails引擎一起使用,使其成为一个没有ID
的新记录。
我应该使用什么算法(或我应遵循的规则)来填写上面的id
以创建新记录?
答案 0 :(得分:3)
"??"
永远不要在你的参数上签好。
使用Cocoon,我看到请求在
id
将要去的空间中有一些数字
ID
只不过是Rails创建的fields_for
数组中的下一个ID。这不是您的记录id
(下面有更多解释)。
从您的设置中,我要做的是:
#app/models/student.rb
class Student < ActiveRecord::Base
has_many :evaluations
has_many :assessments, through: :evaluations
end
#app/models/evaluation.rb
class Evaluation < ActiveRecord::Base
belongs_to :student
belongs_to :assessment
end
#app/models/assessment.rb
class Assessment < ActiveRecord::Base
has_many :evaluations
has_many :students, through: :evaluations
accepts_nested_attributes_for :evaluations, reject_if: :all_blank
end
这将允许您执行以下操作:
#app/controllers/assessments_controller.rb
class AssessmentsController < ApplicationController
def new
@assessment = Assessment.new
@students = Student.all
@students.each do
@assessment.evaluations.build
end
end
end
允许你:
#app/views/assessments/new.html.erb
<%= form_for @assessment do |f| %>
<%= f.fields_for :evaluations, @students do |e| %>
<%= e.hidden_field :student_id %>
<%= e.text_field :grade %>
<% end %>
<%= f.submit %>
<% end %>
据我所知,这将提供您所需的功能。
请注意,每个evaluation
都可以与现有的students
相关联,这意味着如果您提取@students = Student.all
,则会相应地填充fields_for
。
如果您想通过表单添加新students
,那么它的游戏就会略有不同。
<强>茧强>
您还应该清楚Cocoon
的作用。
你看起来像一个经验丰富的开发者,所以我会切入追逐 - 茧是前端,你问的是后端。
具体来说,Cocoon旨在让您能够向表单添加大量fields_for
个关联字段。这在Railscast ...
从技术上讲,Cocoon只是一种为表单创建新fields_for
记录的方法。如果您想动态地添加&#34;只需 字段(RailsCast会告诉你更多)。
因此,如果你想要一个&#34;静态&#34;关联数据字段数组(我想你要问的是什么),您可以使用Max
和我的答案中提交的fields_for
。
答案 1 :(得分:0)
感谢@ rich-peck,我能够弄明白我想做什么。我将他的答案视为已被接受,因为这基本上就是我对自己的回答。 :)
assessments/new.html.haml
(只是原始的,没有花哨的格式化)
= form_for @assessment do |f|
= f.fields_for :evaluations do |ff|
.meaningless-div
= ff.object.student.name
= ff.hidden_field :student_id, value: ff.object.student_id
= ff.label :comment
= ff.text_field :comment
%br/
assessments_controller.rb
def new
@assessment = Assessment.new
@students = Student.all
@students.each do |student|
@assessment.evaluations.build(student: student)
end
end