如何创建将更新所选记录的字段值的表单?

时间:2019-07-13 16:59:18

标签: ruby-on-rails-5 nested-attributes updating

我正在使用来自索引页面的链接,该页面具有一组嵌套记录(行),我需要一次更新所有记录。链接转到一个编辑操作,我需要进行更新以更新嵌套记录(棱镜)的属性。

  1. 我尝试将simple_form gem方法用于嵌套模型。当我只希望一个字段为所有对象输入一个值时,它为我提供了所有对象的字段。生成器看起来很有用,但是我不知道如何使用它来更新字段。无论哪种方式,表单都不正确。

  2. 我尝试了在Google上可以找到的form_for和fields_for的所有变体,以开发编辑表单。看来我是地球上唯一尝试解决此问题的人。

这是我设置路线的方式:

resources :gardens, shallow: true do
    resources :prisms
    resources :rows

这是我的花园模特现在的样子:

class Garden < ApplicationRecord
  mount_uploader :picture, ImageUploader
  belongs_to :user
  has_one :photo
  has_many :rows, :dependent => :destroy
  has_many :prisms
  geocoded_by :address
  after_validation :geocode
  after_commit :populate_garden!

def id
    self[:id]
  end

  def populate_garden!
    # row 0
    (0..length-1).each do |i|
      Row.create(row_num: i, garden_id: id)
    end
  end
end

花园模型通过populate_garden创建我的行!方法。

这是行模型:

class Row < ApplicationRecord
  belongs_to :garden
  has_many :prisms, :dependent => :destroy
  accepts_nested_attributes_for :prisms
  after_commit :populate_rows

  def id
    self[:id]
  end


  def populate_rows
    # row 0
    (0..garden.width-1).each do |i|
        Prism.create(:row_id => self.id, :row_num => self.row_num, :col_num => i, :garden_id => self.garden_id)
    end
  end
end

行模型通过populate_rows方法创建棱镜。

这是棱镜模型:

class Prism < ApplicationRecord
  belongs_to :row
  belongs_to :garden

  include RankedModel
  ranks :column_order
end

这是我单击index.html.erb中的表以打开编辑操作。

<table>

    <% @rows.each_with_index do |gardenrow, index| %>
      <% @rows.select { | row | row.row_num == index}.each do |row| %>

        <td class="prism-cols">
          <%= link_to 'Edit Row', edit_row_path(row), class:"dark-link" %>
          <br /><i class="fas fa-arrow-down"></i>
        </td>

      <% end %>
    <% end %>
</table>

该行很好地传递到了编辑操作中,而我目前的格式不正确:

<h1>The row brought into this form page is: </h1>
<%= @row.inspect %>

<div class="container">
  <%= simple_form_for @row do |m| %>
    <%= m.simple_fields_for :prisms do |p| %>
      <%= p.input :crop_name %>
    <% end %>
    <%= m.button :submit %>
  <% end %>
</div>

rows_controller更新方法如下:

def update
    @row = Row.find(params[:row_id])
    @row.prisms.build
    redirect_to root_path
end

我需要一个crop_name的表单字段,该表单字段将通过一次提交更改所选行中的所有棱镜。通过对棱镜进行编辑操作,一次更新一个棱镜没有任何问题。我遇到的困难是如何在特定行内嵌套棱镜。

在下面我的指导者的帮助下,我能够开发一种与控制器配合使用的表格来完成这项工作。这是更新的代码,以后可用于此类问题。

这是表格数据:

<%= form_tag({controller: "rows", action: "update"}, method: "patch") %>
    <%= label_tag(:crop_name, "Crop Name") %>
    <%= text_field_tag(:crop_name) %>
    <%= hidden_field_tag(:row_id, @row.id) %>
    <%= submit_tag("submit") %>

这是控制器更新方法:

def update
    @row = Row.find(params[:id])
    @garden = Garden.find_by_id(:garden_id)
    @row.prisms.each do |p|
      p.crop_name = params[:crop_name]
      p.save!
    end
    redirect_to :controller => 'gardens', :action => 'show', id: @row.garden_id
  end

感谢您的帮助。我认为我不可能单凭文档就可以解决这个问题。

1 个答案:

答案 0 :(得分:0)

如果我的理解正确,我认为simple_form可能会限制您。基本的红宝石形式可以满足您的需求。我不确定100%对嵌套字段执行simple_form的最佳方法是什么,但是this stackoverflow answer也许可以提供更多帮助。

使用基本的红宝石表格 您需要一种具有一个字段的表单。提交后,它将从提交的表单中获取值,并为该行的所有棱镜更新该字段。我建议针对这种情况深入研究basics of ruby forms,然后执行类似的操作。

// html.erb

<%= form_tag({controller: "rows", action: "update_prism_crop_name"}, method: "post", class: "nifty_form") %>
  <%= label_tag(:crop_name, "Crop name") %>
  <%= text_field_tag(:crop_name) %>
  <%= hidden_field_tag(:row_id, @row.id) %>
  <%= submit_tag("Submit") %>
<% end %>


// rows_controller

def update_prism_crop_name
   @row = Row.find(params[:row_id])
   @row.prisms.each do |prism|
      prism.crop_name = params[:crop_name]
      prism.save!
   end
   # other redirect stuff
end

form_tag显式调用一个动作,但是我不得不想象您也需要为此自定义动作构建一个路由。

我还没有测试过任何一个,但在铁轨上有点生锈,但是我相信类似的东西会起作用。