我有一个在迭代器中呈现的simple_fields_for表单,如下所示:
<%= simple_form_for @port_stock, url: port_stocks_sell_order_path, method: :post, html: { class: "form-inline" } do |f| %>
<% @buy_port_stocks.each do |port_stock| %>
<%= f.simple_fields_for :closed_positions, html: { class: "form-inline" } do |c| %>
<div class="form-group">
<%= c.input_field :port_stock_id, as: :hidden, value: port_stock.id %>
<%= c.input_field :num_units, id: "sell-ps-#{port_stock.id}", placeholder: "Number of Units", class: "form-control mx-sm-3" %>
<%= c.input_field :closed_price, id: "sale-price-for-ps-#{port_stock.id}", placeholder: "Sale Price", class: "form-control mx-sm-3" %>
</div>
<% end %>
<% end %>
<% end %>
在我的控制器中,我有这个:
@port_stock = current_user.port_stocks.friendly.find(params[:id])
@buy_port_stocks = current_user.port_stocks.buy.joins(:stock).where(stocks: { ticker: @stock.ticker})
@cp = @port_stock.closed_positions.build
我的PortStock.rb
模型:
has_many :closed_positions, dependent: :destroy
accepts_nested_attributes_for :closed_positions, allow_destroy: true
我的ClosedPosition.rb
模型:
class ClosedPosition < ApplicationRecord
belongs_to :closer, class_name: "PortStock", foreign_key: "closer_id"
belongs_to :closed, class_name: "PortStock", foreign_key: "port_stock_id"
end
对于没有@port_stock
的{{1}}条记录,以上方法非常适用。
例如,该表单的呈现方式如下:
请注意,closed_positions
和Number of Units
字段在每行中只显示一次(这是我期望的)。
但是,一旦我在任何Sale Price
上创建了closed_position
,它就会产生两个问题:
第一期
它将现有的平仓头寸预先填充为一个字段,然后为PortStock
渲染另一个空白字段,即:
我要发生的事情是,它仅呈现新表单,而不重新呈现每行上现有的closed_position值。用户应该无法在此表单中编辑现有的平仓头寸。
第二期
只要有多个平仓,它就会在每一行中显示错误的位置。
请注意,呈现的每个值如何表示closed_positions
&& num_units: 100
,请查看相同的closed_positions的控制台输出:
price: 8.0
正确的值实际上是:
我不明白为什么它为所有=> [#<ClosedPosition:0x00007ff13e77c6d0
id: 9,
closer_id: 2,
port_stock_id: 17,
num_units: 100,
closed_price: 8.0,
ticker: "CAC",
#<ClosedPosition:0x00007ff13e77c2e8
id: 10,
closer_id: 3,
port_stock_id: 18,
num_units: 10,
closed_price: 7.95,
ticker: "CAC",
#<ClosedPosition:0x00007ff13e77c018
id: 11,
closer_id: 10,
port_stock_id: 19,
num_units: 50,
closed_price: 7.9,
ticker: "CAC",
对象输出相同的值。
如何以port_stock
格式解决这两个问题?
答案 0 :(得分:1)
好的,让我指导我的逻辑并不牢固,但我将其基于ActionView::Helpers::FormHelper
无论使用simple_form
还是标准的Rails助手,传递关联记录和关联模型之间都存在差异。
<%= form_for @record %>
<%= fields_for @associated_record %>
vs。
<%= form_for @record %>
<%= fields_for :associated_model %>
我相信这与在不存在一个新记录时实例化一个新记录有关。
因此,我在评论中的第一步是建议使用更具体的记录变量:
:closed_positions @cp
因此:
<%= simple_form_for @port_stock, url: port_stocks_sell_order_path, method: :post, html: { class: "form-inline" } do |f| %>
<% @buy_port_stocks.each do |port_stock| %>
<%= f.simple_fields_for @cp, html: { class: "form-inline" } do |c| %>
...
正如您评论的那样,这不是一个完美的解决方案,但确实可以解决重复的字段。
但是,正如您的控制器所指出的那样,@cp
不是与@buy_port_stocks
的直接关联,而这正是表单所循环通过的内容。
因此,您真正发现的解决方案是声明两者,这是允许的:
字段可以通过两种方式反映模型对象:它们的命名方式(因此,提交的值如何在控制器的params哈希中显示)以及首次显示字段所用的表单时显示的默认值。为了分别指定这两个功能,可以将对象名称(用符号或字符串表示)和对象本身分别传递给方法
文档建议同时声明两者,在您的情况下看起来像这样:
<%= simple_form_for @port_stock, url: port_stocks_sell_order_path, method: :post, html: { class: "form-inline" } do |f| %>
<% @buy_port_stocks.each do |port_stock| %>
<%= f.simple_fields_for :closed_positions, @cp, html: { class: "form-inline" } do |c| %>
...
虽然我显然会获得与正确答案相关的财富和名望,但是公平地承认我并不是一个人陪着你。