1

我有一个在迭代器中呈现的 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没有closed_positions.

例如,该表单呈现如下:

simple_form_for 的良好渲染

请注意,Number of UnitsandSale Price字段在每一行中只显示一次(这是我所期望的)。

但是,一旦我closed_position在 any 上创建了一个,PortStock它就会产生两个问题:

首要问题

它将现有的已平仓头寸预填充为一个字段,然后为 渲染另一个空白字段closed_positions,即像这样:

首要问题

我想要发生的是它只呈现新表单而不是重新呈现每行上现有的 closed_position 值。用户不能在此表单中编辑现有的已平仓头寸。

第二期

每当有多个已平仓头寸时,它都会在每一行中呈现错误的头寸。

为每个关闭位置呈现的错误值

请注意呈现的每个值是如何表示num_units: 100&&price: 8.0的,请查看这些相同 closed_positions 的控制台输出:

=> [#<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",

正确的值实际上是:

  1. 数量单位:100 && 价格:8.0
  2. 数量单位:10 && 价格:7.95
  3. 数量单位:50 && 价格:7.9

我不明白为什么它为所有port_stock对象输出相同的值。

如何在我的simple_fields_for表单中解决这两个问题?

4

1 回答 1

1

好的,让我用我的逻辑不可靠来指导这个,但我基于ActionView::Helpers::FormHelper

不管是什么simple_form标准的 Rails 助手,传递关联的记录和关联的模型是有区别的。

<%= form_for @record %>
  <%= fields_for @associated_record %>

对比

<%= form_for @record %>
  <%= fields_for :associated_model %>

而且我相信这与在不存在时实例化新记录有关。

所以,我在评论中的第一个摇摆是建议使用更具体的记录变量:

:close_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| %>
      ...

虽然我显然会接受与正确答案相关的财富和名望,但公平地说,我并没有让你一个人到达那里。

于 2018-06-27T17:41:02.037 回答