【问题标题】:Rails - How to split nested attributes through the form?Rails - 如何通过表单拆分嵌套属性?
【发布时间】:2017-03-08 00:58:37
【问题描述】:

我知道我们可以使用 fields_for 为嵌套属性创建字段的子部分。但是,我想通过表格将它们分开。我该怎么做?

例如:

假设我有一个带有嵌套 bar 模型的模型 foo,如下所示:

class Foo < ApplicationRecord
  has_many :bars
  accepts_nested_attributes_for :bars
end

一般视图是这样的:

<%= form_for @foo do |f| %>
  <!-- foo fields -->

  <%= f.fields_for :bars do |f_bar| %>
    <!-- bar fields -->
  <% end %>

  <%= f.submit "Submit" %>
<% end %>

但出于美学原因,我不希望所有bars 聚集在一个地方。我想做类似的事情:

<%= form_for @foo do |f| %>
  <!-- foo fields -->

  <%= f.fields_for :bars do |f_bar| %>
    <!-- bar fields of one bar -->
  <% end %>

  <!-- other foo fields -->

  <%= f.fields_for :bars do |f_bar| %>
    <!-- bar fields of another bar -->
  <% end %>

  <!-- The previous repeats many more times in a non predictable way -->

  <%= f.submit "Submit" %>
<% end %>

如果我不必一次显示所有bars,那对我来说是完美的。有人知道怎么做吗?

【问题讨论】:

  • 你试过了吗?
  • 您可以尝试像使用@foo 一样传递实例变量。将单条过滤掉到一个实例变量中,然后放到控制器中的另一个变量中,您可以在视图中使用它。
  • 单变量个数未确定。这只是一个例子..
  • 应该可以。

标签: ruby-on-rails forms nested-attributes fields-for


【解决方案1】:

所以,我只需要让fields_for 每次只显示一个实例。

我发现fields_for 允许您指定特定对象来呈现字段。所以,我刚刚创建了一个计数器,每次添加一个@foo.bars[counter],它神奇地起作用了,它是这样的:

<% counter = 0 %>
<%= form_for @foo do |f| %>

  <!-- foo fields -->

  <%= f.fields_for :bars, @foo.bars[counter] do |f_bar| %>
    <!-- bar fields of one bar -->
  <% end %>
  <% counter+=1 %>

  <!-- other foo fields -->

  <%= f.fields_for :bars, @foo.bars[counter] do |f_bar| %>
    <!-- bar fields of another bar -->
  <% end %>
  <% counter+=1 %>

  <!-- The previous repeats many more times in a non predictable way -->

  <%= f.submit "Submit" %>
<% end %>

【讨论】:

    【解决方案2】:

    您可以使用fields_for 的第二个参数并传递一个范围:

    class Bar < ApplicationRecord
    
      belongs_to :foo
    
      scope :some_a,->{where(conditions)}
      scope :some_b,->{where(conditions)}
    
    end
    

    在您的表单中

    <%= form_for @foo do |f| %>
        <%= f.text_field :foo_attr %>
    
        <%= f.fields_for :bars, @foo.bars.some_a do |b| %>
            <%= b.hidden_field :other_bar_attr %>
            <%= b.text_field :bar_attr %>
            ...
        <% end %>
    
        <%= f.fields_for :bars, @foo.bars.some_b do |b| %>
            <%= b.hidden_field :other_bar_attr %>
            <%= b.text_field :bar_attr %>
            ...
        <% end %>
        <%= f.submit %>
    <% end %>
    

    您可以使用隐藏的输入来设置作用域中使用的默认值。

    更新

    如果您需要在表单中使用多个 fields_for 实例,您可以这样做

    在控制器中为作用域对象设置一个数组,例如:

    class SomeController < AP
      def some_action
        @var_to_the_form = []
        (1..well_know_quantity).each do |value|
          @var_to_the_form << Model.where(conditions)
        end
      end
    end
    

    你的表格必须如下

    <% @var_to_the_form.each do |records| %>
      <%= f.fields_for :bars, records do |b| %>
        <%= b.hidden_field :other_bar_attr %>
        <%= b.text_field :bar_attr %>
            ...
      <% end %>
    <% end %>
    

    重要的部分是知道如何设置你传递给视图的记录。

    【讨论】:

    • 我喜欢您的解决方案,但它并不真正适合我的问题,因为范围很多且不可预测。
    • 是说范围不可预测?或者您是想说您认为fields_for 的数量在每种情况下都不相同?
    • fields_for 的数量在每种情况下都不相同.. 抱歉混淆:/
    • 我知道如何解决它。你能从你的控制器知道这个“数量”吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    相关资源
    最近更新 更多