Rails has_many 与预填充视图的关系
Rails has_many relationship with prefilled views
我有一个非常基本的 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
所在的 space 中有一些数字(我在下面用 ??
替换了这些)。
{"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 引擎一起工作的,从而在没有 [=20= 的情况下将其变成新记录].
上面的id
填写应该用什么算法(或者说应该遵循什么规则)来创建新的记录?
"??"
你的参数绝对不是好兆头。
With Cocoon I see that requests have some number in the space where the id
would go
那个 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 是前端,您问的是后端。
具体来说,Cocoon 旨在让您能够向表单添加多个 fields_for
关联字段。这在 Railscast...
中进行了讨论
从技术上讲,Cocoon 只是一种为表单创建新 fields_for
记录的方法。如果您想动态 "add" 字段,则 仅 是必需的(RailsCast 会告诉您更多信息)。
因此,如果您只想拥有一个 "static" 关联数据字段数组(我想这就是您要问的),您将能够使用提交的 fields_for
在 Max
和我的回答中。
多亏了@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
我有一个非常基本的 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
所在的 space 中有一些数字(我在下面用 ??
替换了这些)。
{"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 引擎一起工作的,从而在没有 [=20= 的情况下将其变成新记录].
上面的id
填写应该用什么算法(或者说应该遵循什么规则)来创建新的记录?
"??"
你的参数绝对不是好兆头。
With Cocoon I see that requests have some number in the space where the
id
would go
那个 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 是前端,您问的是后端。
具体来说,Cocoon 旨在让您能够向表单添加多个 fields_for
关联字段。这在 Railscast...
从技术上讲,Cocoon 只是一种为表单创建新 fields_for
记录的方法。如果您想动态 "add" 字段,则 仅 是必需的(RailsCast 会告诉您更多信息)。
因此,如果您只想拥有一个 "static" 关联数据字段数组(我想这就是您要问的),您将能够使用提交的 fields_for
在 Max
和我的回答中。
多亏了@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