2017-01-19 29 views
1

私はこれについて想像できるすべての投稿を見てきましたが、解決策を見つけることはできません。私は他のデータベースからIDを取得するTask Productsのネストされたリソースを持つTaskを持っています。タスクにネストされた複数のタスクプロダクトが存在することがあり、それぞれがいくつかのJavascriptとApplication Helper(どちらも純粋に自分のコピー/ペースト)で動的に作成されます。ネストされた属性の許可されていないパラメータ

Railscast 196/197this postの助けを借りて、これらのネストされたパラメータのコードを構築しました。すべての関連するコードは以下の通りですし、問題へ:

task.rb:

class Task < ApplicationRecord 
    has_many :task_products, :dependent => :destroy 
    accepts_nested_attributes_for :task_products, :reject_if => lambda { |p| p.values.all?(&:blank?) }, :allow_destroy => true 
end 

task_controller.rb:

class TasksController < ApplicationController 

    def new 
    @task = Task.new 
    @task.task_products.build 
    end 

    def task_params 
    params.require(:task).permit(:id, :task_name, . . ., :created_at, :updated_at, 
           :task_products_attributes => [:task_id, :product_id, :created_at, :updated_at]) 
end 

がapplication_helper.rb:

module ApplicationHelper 

    def new_child_fields_template(form_builder, association, options = {}) 
    options[:object] ||= form_builder.object.class.reflect_on_association(association).klass.new 
    options[:partial] ||= association.to_s.singularize 
    options[:form_builder_local] ||= :f 

    content_tag(:div, :id => "#{association}_fields_template", :style => "display: none") do 
     form_builder.fields_for(association, options[:object], :child_index => "new_#{association}") do |f| 
     render(:partial => options[:partial], :locals => { options[:form_builder_local] => f }) 
     end 
    end 
    end 

application.js:

$(function() { 
    $('form a.add_child').click(function() { 
    var association = $(this).attr('data-association'); 
    var template = $('#' + association + '_fields_template').html(); 
    var regexp = new RegExp('new_' + association, 'g'); 
    var new_id = new Date().getTime(); 
    $(this).parent().before(template.replace(regexp, new_id)); 
    return false; 
    }); 
}); 

_form.html.erb:

<%= form_for @task, url: tasks_path, method: :post, :html => {:multipart => true } do |f| %> 
    <%= f.fields_for :task_products, TaskProduct.new do |builder| %> 
     <%= render "task_product", :f => builder %> 
    <% end %> 
    <p><%= add_child_link "Add Product", :task_products %></p> 
    <%= new_child_fields_template f, :task_products %> 

_task_product.html.erb:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"KDQ...8bxur2A==", 
"task"=>{"task_type"=>"Store Order", 
    "task_products_attributes"=>{ 
    "0"=>{"product_id"=>"1", "_destroy"=>"false"}, 
    "1484792726712"=>{"product_id"=>"2", "_destroy"=>"false"}, 
    "new_task_products"=>{"product_id"=>"", "_destroy"=>"false"}}, 
    "initiated_by"=>"1", "initiated_for"=>"5", "active"=>"true", "status"=>"Pending Acceptance"}, 
"commit"=>"Create Task"} 

Unpermitted parameters: 0, 1484792726712, new_task_products 

生成:コンソールで

<div class="fields"> 
    <div class="form-group"> 
    <%= f.label :product_id, "Product:", class: 'col-sm-3 control-label' %> 
     <%= f.collection_select(:product_id, @items, :id, :item_select, {:include_blank => 'Select Item...'}, {:class => 'form-control'}) %> 
     <%= remove_child_link "Remove Product", f %> 
    </div> 
</div> 

コードの後、それが生成されたエラーと一緒に提出複数生成された選択のエラー生成コードのHTML例:

<select class="form-control" name="task[task_products_attributes][0][product_id]" id="task_task_products_attributes_0_product_id"> 
<select class="form-control" name="task[task_products_attributes][1484794199756][product_id]" id="task_task_products_attributes_1484794199756_product_id"> 

と私は戻って投げしなければならないと思ったそのテンプレート、コンソールで「『_destroy』 => true」を?:

<select class="form-control" name="task[task_products_attributes][new_task_products][product_id]" id="task_task_products_attributes_new_task_products_product_id"> 

問題、上で見たように、私の生成タスク製品の形ということです各項目の選択ボックスに追加の括弧で囲まれた識別子(子インデックス?)を追加していますが、アプリケーションヘルパーにそれを削除する方法やそれが属する場所に移動する方法がわかりません。それともそれが実際にそこに属していて、何か間違っているのですか?私は個々のタスクプロダクトにそれ自身の一意の識別子を持たなければならないと感じていますが、Railsはこれを持っておらず、許されていないと言います。

アプリケーションヘルパーの 'new_child_fields_template'は私の頭の中に少しありますが、タスク製品フォームに注入する一意の識別子がどのようになっているのか理解していますが、どのように「名前= "私の選択のフィールドは明らかにすべてをねじ込んでいます。誰も私がこの問題をどのように乗り越えることができるかについての指針を持っていますか?ありがとう!

+0

私は、あなたが話している隠されたフィールドに同様の問題があったと信じています。 'http:// api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html'で' CTRL + F'と 'include_hidden'を検索してください。 これを '#collection_check_boxes'のparamとして使うことができます。 '= collection_check_boxes(:オブジェクト、フィールド、[opts]、:メソッド1、:メソッド2、{include_hidden:false}、...&ブロック' – Shiyason

+0

これが役立つかどうかを参照してください[強いパラメータを持つ配列を許可する方法://stackoverflow.com/a/30285592/2981429) –

+0

@maxple、リンクありがとうございます(後で便利になります)が、これは私が達成しようとしているとは思わない。アプリケーションヘルパーから、選択ドロップダウンの「名前」フィールドに追加値が入力され、フォームの値として渡そうとしていますが、値として渡す必要はありません。タスクプロダクトがタスクの一部にリンクされていることを確認する(自動的に行われると思う)ので、名前欄に2番目の括弧で囲まれた項目を取り除く方法を理解するだけです –

答えて

1

強い属性でうまく機能するには、属性のリストにid属性と_destroy属性を渡す必要があります。あなたのtasks_controller.rbで:

params.require(:task).permit(
    task_products_attributes: [ 
     :id, :product_id, :created_at, :updated_at, :_destroy 
    ] 
) 

明確に説明するために、あなたはこのanswerに行くことができます。

+0

あなたはdinamically生成されたフィールドを使うことができるので、次のようなものを忘れる危険はありません: 'task_products_attributes:([:_destroy] + TaskProducts.column_names.map(&:to_sym))' – ErvalhouS

+0

@zamakkatあなたがリンクしている投稿は、私が持っているのと全く同じ問題を説明していますが、「許可されていないパラメータ」の問題は解決しません。これは信念を超えてイライラしています。なぜなら、これが何を働かせないのか分からないから、考えられるあらゆる解決策を見てきました。 –

+0

Clarification:これは私のparams.requireの現在のもので、 "0" =>などのパラメータの "Unpermitted"エラーをスローしています:: task_products_attributes:[:product_id、:task_id、:created_at、 = "{0" => {"product_id" => "2"、 "_destroy" =、 "_destroy" > "false"}、 "1484881558666" => {"product_id" => "3"、 "_destroy" => "false"}、 "new_task_products" => {"product_id" => ""、 "_destroy" => "false"}}、。 。 。 許可されていないパラメータ:0、1484881558666、new_task_products –

0

最終的なコメントは、ネストされたパラメータに ":id"を含めることがなぜ機能しないのかについての追加の入力がない限りです。それは、ネストされたのですかどうか、タスク・パラメータ:私は最終的にそれが明らかに

params.require(:task).permit! 

これに対して許可パラメータを変更することにより、作業しまった

はに陥ることを起こる何のための毛布許可証です。私はこれが推奨されていないことを集めていますが、そのサイトは非常に少数のチームメンバーと締結されているので、これは問題ではないと思いますか?さらに、私はまだ "new_task_products"のテンプレートがproduct_idが空白なので、 "destroy => 1"を与えてくれない理由についての洞察を探しています。このコードは正しくありませんか?

accepts_nested_attributes_for :task_products, 
    :reject_if => lambda { |p| p.values.all?(&:blank?) }, 
    :allow_destroy => true 

問題を回避するために、テンプレートをビューの外に移動しようとする可能性があります。みんな助けてくれてありがとう!

関連する問題