如何创建一个表单来更新所选记录的字段值?
How do I create a form that will update the value of a field for selected records?
我正在使用来自索引页的 link,该页有一组我需要一次全部更新的嵌套记录(行)。 link 转到我需要更新嵌套记录(棱镜)属性的编辑操作。
我尝试对嵌套模型使用 simple_form gem 方法。当我只希望一个字段为所有对象输入一个值时,它为我提供了一个用于所有对象的字段。该构建器看起来可用,但我不知道如何使用它来更新字段。不管怎样,表格都不对。
我已经尝试了 form_for 和 fields_for 我能在 Google 上找到的所有变体来开发编辑表单。看来我是地球上唯一一个试图解决这个问题的人。
这是我设置路线的方式:
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,我点击它打开了编辑操作。
<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
感谢您的帮助。我认为我无法仅从文档中弄清楚这一点。
如果我理解正确,我认为 simple_form
可能限制了您。一个基本的 ruby 表单可以满足您的需求。我不是 100% 确定在嵌套字段上执行 simple_form
的最佳方法是什么,但 this Whosebug answer 可能会提供更多帮助。
使用基本的 ruby 形式
您想要一个只有一个字段的表单。提交时,它将从提交的表单中获取值并更新该行所有棱镜的字段。对于这种情况,我建议深入研究 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 明确调用了一个操作,但我不得不想象您还需要为这个自定义操作构建一个路由。
我还没有测试过这些,我对 rails 有点生疏,但我相信这样的事情会奏效。
我正在使用来自索引页的 link,该页有一组我需要一次全部更新的嵌套记录(行)。 link 转到我需要更新嵌套记录(棱镜)属性的编辑操作。
我尝试对嵌套模型使用 simple_form gem 方法。当我只希望一个字段为所有对象输入一个值时,它为我提供了一个用于所有对象的字段。该构建器看起来可用,但我不知道如何使用它来更新字段。不管怎样,表格都不对。
我已经尝试了 form_for 和 fields_for 我能在 Google 上找到的所有变体来开发编辑表单。看来我是地球上唯一一个试图解决这个问题的人。
这是我设置路线的方式:
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,我点击它打开了编辑操作。
<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
感谢您的帮助。我认为我无法仅从文档中弄清楚这一点。
如果我理解正确,我认为 simple_form
可能限制了您。一个基本的 ruby 表单可以满足您的需求。我不是 100% 确定在嵌套字段上执行 simple_form
的最佳方法是什么,但 this Whosebug answer 可能会提供更多帮助。
使用基本的 ruby 形式 您想要一个只有一个字段的表单。提交时,它将从提交的表单中获取值并更新该行所有棱镜的字段。对于这种情况,我建议深入研究 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 明确调用了一个操作,但我不得不想象您还需要为这个自定义操作构建一个路由。
我还没有测试过这些,我对 rails 有点生疏,但我相信这样的事情会奏效。