我正在使用来自索引页面的链接,该页面具有一组嵌套记录(行),我需要一次更新所有记录。链接转到一个编辑操作,我需要进行更新以更新嵌套记录(棱镜)的属性。
我尝试将simple_form gem方法用于嵌套模型。当我只希望一个字段为所有对象输入一个值时,它为我提供了所有对象的字段。生成器看起来很有用,但是我不知道如何使用它来更新字段。无论哪种方式,表单都不正确。
我尝试了在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
感谢您的帮助。我认为我不可能单凭文档就可以解决这个问题。
答案 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显式调用一个动作,但是我不得不想象您也需要为此自定义动作构建一个路由。
我还没有测试过任何一个,但在铁轨上有点生锈,但是我相信类似的东西会起作用。