Rails 5.2:如何创建fields_for每个I18n键值?

Rails 5.2: How to create fields_for each I18n key value?

在我的 _form.html.erb 中,我有嵌套字段,对于优惠,我想在其中保存多个折扣类型,值:

<%= f.fields_for @offer.discounts do |discount| %>
  <% I18n.t(:discount_type).each do |type| %>
     <div class="form-group row discount-list">
       <label class="col-sm-8 control-label">
          <%= discount.label I18n.t("discount_type.#{type[0]}") %><br/>
       </label>
       <div class="col-sm-4">
         <%= discount.hidden_field :discount_type, value: type[0] %>
         <%= discount.number_field :value, 
             value: (@offer.new_record? ? '0.00' : discount.value), 
             class: "form-control allow_numeric" %>
      </div>
    </div>
  <% end %>
<% end %>

目前我的表单已按照我希望的方式正确填充,但是值未保存,因为:

  1. 在我的参数中,我只看到 3 种折扣类型中的一种,如下所示: "seller_discount"=>{"discount_type"=>"special", "value"=>"5"}
  2. 有错误Unpermitted parameter: :seller_discount
  3. 记录未保存

我的 Seller::Offer 模型如下所示:

has_many :offer_discounts, class_name: "Seller::OfferDiscount"
has_many :discounts, class_name: "Seller::Discount", through: :offer_discounts, inverse_of: :offers
accepts_nested_attributes_for :discounts, allow_destroy: true

我的控制器很简单:

  def new
    @offer = Seller::Offer.new
  end

  private

  def offer_params
    params.require(:seller_offer).permit(
      :company_id, :name, :base_price,
      discounts_attributes: [:id, :discount_type, :value, :_destroy]
    )
  end

到目前为止,我一直在尝试与 Rails docs 不同的想法,但没有成功。可能在我的具体情况下,扭曲是我尝试迭代 I18n.t(:discount_type) 为每个折扣类型(购买密钥)创建输入字段的地方。

如果有任何解决此问题的提示,我将很高兴。谢谢!

由于您要遍历 discount_type,我认为您的 offer_params 方法中必须是数组类型。

def offer_params
  params.require(:seller_offer).permit(
    :company_id, :name, :base_price,
    seller_discounts_attributes: [:id, :discount_types => [:discount_type, :value], :_destroy]
  )
end

但是如果您尝试使用 fields_for 助手会怎样?

<%= f.fields_for @offer.discounts do |discount| %>
  <%= f.fields_for I18n.t(:discount_type) do |type| %>
     <div class="form-group row discount-list">
       <label class="col-sm-8 control-label">
          <%= discount.label I18n.t("discount_type.#{type[0]}") %><br/>
       </label>
       <div class="col-sm-4">
         <%= discount.hidden_field :discount_type, value: type[0] %>
         <%= discount.number_field :value, 
             value: (@offer.new_record? ? '0.00' : discount.value), 
             class: "form-control allow_numeric" %>
      </div>
    </div>
  <% end %>
<% end %>

因此,要让我的表单同时适用于新建和编辑操作,最终解决方案是:

        <% if params[:action] == 'new' %>
        <div class="col-md-7 col-sm-7">
        <!-- Discounts for new form !-->
          <% I18n.t(:discount_type).each do |type| %>
          <%= f.fields_for :discounts, @offer.discounts.build do |disc| %>
              <div class="form-group row discount-list">
                <label class="col-sm-8 control-label">
                  <%= disc.label I18n.t("discount_type.#{type[0]}") %><br/>
                </label>
                <div class="col-sm-4">
                  <%= disc.hidden_field :discount_type, value: type[0] %>
                  <%= disc.number_field :value, value: '0.00',
                      class: "form-control allow_numeric" %>
                </div>
              </div>
            <% end %>
          <% end %>
        </div>
        <% elsif params[:action] == 'edit' %>
        <div class="col-md-7 col-sm-7">
        <!-- Discounts for edit form !-->
        <%= f.simple_fields_for :discounts do |d| %>
          <div class="form-group row discount-list">
            <%= d.input :discount_type, as: :hidden %>
            <label class="col-sm-8 control-label">
              <%= d.label I18n.t("discount_type.#{d.object.discount_type}") %><br/>
            </label>
            <div class="col-sm-4">
              <%= d.input :value, label: false, input_html: { id: d.object.discount_type+"_discount",
                  class: "form-control allow_numeric" } %>
            </div>
          </div>
        <% end %>
        </div>
      <% end %>

编辑操作已完成 simple_form_fields_for

显然不是很好的解决方案,但看起来可行。