Rails与预先填充的视图有很多关系

时间:2015-10-24 05:38:08

标签: ruby-on-rails ruby-on-rails-4 nested-forms cocoon-gem

我有一个非常基本的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以创建新记录?

2 个答案:

答案 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 ...

中进行了讨论

enter image description here

从技术上讲,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