代码之家  ›  专栏  ›  技术社区  ›  marcamillion blelump

如何防止窗体出现多个简单字段?

  •  1
  • marcamillion blelump  · 技术社区  · 6 年前

    对于在迭代器中呈现的表单,我有一个简单的字段,如下所示:

    <%= 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 是的。

    例如,该表单的呈现方式如下:

    good-rendering-of-simple_form_for

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

    但是,一旦我创建了 closed_position 在任何 PortStock 它产生了两个问题:

    第一期

    它预先将现有的关闭位置作为字段填充,然后为 关闭位置 ,例如:

    first-issue

    我希望它只呈现新表单,而不是重新呈现每行上现有的closed_position值。用户不能在此表单中编辑现有的关闭位置。

    第二期

    每当有多个闭合位置时,它会在每行中呈现错误的位置。

    wrong-values-rendered-for-each-closed-position

    请注意呈现的每个值是如何表示的 num_units: 100 &amp; 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",
    

    正确的值实际上是:

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

    我不明白为什么所有的 port_stock 物体。

    我该如何解决这两个问题 simple_fields_for 形式?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Chiperific    6 年前

    好吧,让我来指导一下,我的逻辑是不可靠的,但我是基于 ActionView::Helpers::FormHelper

    不管 simple_form 或者标准的rails助手,传递关联的记录和关联的模型是有区别的。

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

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

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

    因此,我在评论中的第一个转变是建议使用更具体的记录变量:

    :关闭位置 @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| %>
          ...
    

    虽然我很明显会把财富和名望与正确答案联系起来,但承认我并不是一个人带你去的,这是公平的。

    推荐文章