【问题标题】:Model with nested attributes doesn't show fields_for in field that is not an attribute in the model具有嵌套属性的模型在不是模型中的属性的字段中不显示 fields_for
【发布时间】:2020-09-05 22:37:39
【问题描述】:

我有一个Exam 和一个ExamBattery,它们只是Exams 的集合。它们彼此有一个has_and_belong_to_many 声明,ExamBattery 接受Exam 的嵌套属性,如下所示:

class Exam < ApplicationRecord
  has_and_belongs_to_many :exam_batteries
  validates_presence_of :name
end

class ExamBattery < ApplicationRecord
  has_and_belongs_to_many :exams
  accepts_nested_attributes_for :exams, reject_if: lambda { |attrs| attrs['name'].blank? }
  validates_presence_of :name
end

当我创建一个新的Exam 时,我希望能够将其分配给一个或多个ExamBatteries,因此在ExamsController 中我将数组exam_battery_ids 列入白名单以接受多个ExamBatteries 以将它们分配给当前的Exam(没有进行其他更改,控制器只是来自脚手架):

def exam_params
  params.require(:exam).permit(:name, :description, :order, :price, exam_battery_ids: [])
end

另外,在 exams/new 视图中,我添加了一个多选以将所需的 exam_battery_ids 作为参数发送:

 <%= form_with(model: exam, local: true) do |form| %>
   # ... typical scaffold code
   <div class="field">
     <% selected = exam.exam_batteries.collect { |eb| eb.id } %>
     <%= form.label :exam_battery_ids, 'Add batteries:' %>
     <%= form.select :exam_battery_ids,
                options_from_collection_for_select(ExamBattery.all, :id, :name, selected),
                { prompt: 'None' },
                multiple: true %>
   </div>
 <% end %>

这个想法是能够以相同的形式创建一个新的ExamBattery,其中包含新的Exams(我还没有写那部分,我现在只能编辑)。此外,当我编辑ExamBattery 时,我希望能够编辑它的Exams,甚至将它们分配给其他ExamBatteries(如果我选择“无”,或者只是另一个考试电池,它将停止分配给当前ExamBattery),所以在exam_batteries/edit(实际上是其中的部分形式)我有这个代码:

<%= form_with(model: exam_battery, local: true) do |form| %>
  # ... normal scaffold code
  <div class="field">
    <!-- it should be exam_battery[exams_attributes][#_of_field][order] -->
    <!-- it is exam_battery[exam_battery_ids][] -->
    <% selected = exam_battery.exams.map { |exam| exam.id } %>
    <%= form.label :exam_battery_ids, 'Edit batteries:' %>
    <%= form.select :exam_battery_ids,
                    options_from_collection_for_select(ExamBattery.all, :id, :name, selected),
                    { prompt: 'None' },
                    multiple: true %>
  </div>
<% end %>

ExamBatteriesController 中,我将exam_batteries_attributes 列入白名单,并以exam_battery_ids: [] 作为参数:

params.require(:exam_battery).permit(:name, :certification, exams_attributes: [:name, :description, :order, :price, exam_battery_ids: []])

但是当我在ExamBattery 表单中尝试编辑Examexam_batteries 时,信息不会更新,因为参数是这样的:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"blah", "exam_battery"=>{"name"=>"Battery1", "certification"=>"test1", "exams_attributes"=>{"0"=>{"name"=>"Exam1", "description"=>"", "order"=>"", "id"=>"3"}, "1"=>{"name"=>"Exam2", "description"=>"", "order"=>"", "id"=>"4"}, "2"=>{"name"=>"Exam3", "description"=>"", "order"=>"", "id"=>"5"}}, "exam_battery_ids"=>["", "", "", "", "", "3"]}, "commit"=>"Update Exam battery", "id"=>"3"}

exam_battery_ids 作为不同的参数发送,因为选择名称是 exam_battery[exam_battery_ids][] 而不是 exam_battery[exams_attributes][0][name] 之类的名称,就像其他字段一样。我该如何解决?

谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-5 nested-attributes fields-for


    【解决方案1】:

    我的表格有误。在exam_batteries/edit 中我没有注意到我使用的是form_with 变量(表单)而不是fields_for 变量(构建器),所以应该是这样的:

    <div class="field">
      <!-- it should be exam_battery[exams_attributes][0][order] -->
      <!-- it is exam_battery[exam_battery_ids][] -->
      <% selected = exam_battery.exams.map { |exam| exam.id } %>
      <%= builder.label :exam_battery_ids, 'Escoge una batería' %>
      <%= builder.select :exam_battery_ids,
                      options_from_collection_for_select(ExamBattery.all, :id, :name, selected),
                      {
                        include_hidden: false,
                        prompt: 'Ninguna'
                      },
                      multiple: true %>
    </div>
    

    这样它应该可以工作。 现在唯一的问题是,当我在 fields_for 中显示所选电池时,我无法获取它们,但我正在努力。

    更新:我可以通过将视图中的选定变量替换为以下内容,以嵌套形式显示考试的当前考试电池:

    <% selected = exam_battery.exams[builder.options[:child_index]].exam_batteries.map { |eb| eb.id } %>
    

    如果您知道更清洁的方法,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多