0

ネストされたフォームとhas_manyの関係に問題があります。ビジネスケース:研究室とそのサプライヤがあります。サプライヤはラボ間で共有することができます。Rails 4つのネストされたフォームで、has_many、throughとmultipleを選択します。

モデル

class Lab < ActiveRecord::Base 
    has_many :lab_suppliers 
    has_many :suppliers, through: :lab_suppliers 
    accepts_nested_attributes_for :lab_suppliers 
end 

class Supplier < ActiveRecord::Base 
    has_many :lab_suppliers 
    has_many :labs, through: :lab_suppliers 
    accepts_nested_attributes_for :lab_suppliers 
end 

class LabSupplier < ActiveRecord::Base 
    belongs_to :lab 
    belongs_to :supplier 

    accepts_nested_attributes_for :lab 
    accepts_nested_attributes_for :supplier 
end 

フォーム

<%= form_for(@lab) do |f| %> 
    <div class="field"> 
    <%= f.label :code %><br> 
    <%= f.text_field :code %> 
    </div> 
    <div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 
    <div class"field"> 
    <%= fields_for :lab_suppliers do |ff| %> 
     <%= ff.label :supplier_id %><br> 
     <%= ff.collection_select :supplier_id, Supplier.all, :id, :name, {include_blank: true}, {:multiple => true, :class=>""} %> 
    <% end %> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

コントローラAFTEのparamsに検査の

class LabsController < ApplicationController 
    before_action :set_lab, only: [:show, :edit, :update, :destroy] 

    # GET /labs/new 
    def new 
    @lab = Lab.new 
    @lab.lab_suppliers.build 
    end 

    # POST /labs 
    # POST /labs.json 
    def create 
    #raise params.inspect 

    @lab = Lab.new(lab_params) 

    @lab_supplier = @lab.lab_suppliers.new(params[:lab_suppliers]) 
    @lab_supplier.save 
    @lab.save 


    private 

    def lab_params 
     params.require(:lab).permit(:code, :name, lab_suppliers_attributes: []) 
    end 
end 

結果私は期待通りに動作させるために何をしないのです

@lab_supplier = @lab.lab_suppliers.new(params[:lab_suppliers]) 

:私はActiveModelを受け取る:: ForbiddenAttributesError 行にフォームを送信しながら

{"utf8"=>"✓", 
"authenticity_token"=>"...", 
"lab"=>{"code"=>"L01", 
"name"=>"xxx"}, 
"lab_suppliers"=>{"supplier_id"=>["", 
"1", 
"3"]}, 
"commit"=>"Create Lab"} 

パラメータ:rのフォームを提出しますか?

答えて

1

あなたは明示的には以下のように渡す必要がlab_suppliersからどの属性をlab_paramsを伝える必要がありますように思える:それを試してみて、私に知らせて

params.require(:lab).permit(:code, :name, lab_suppliers_attributes: [:supplier_id]) 

+0

いいえ、私はそれを試しても、同じエラーが表示されます。私は問題がlab_suppliersのparamsがlab_paramsにネストされていないと思っています。 – Michal

+0

:<%= fields_for:lab_suppliers do | ff | %>しようとする<%= f.fields_for:lab_suppliers do | ff | %>そう、fを置く – loloso

+0

あなたは正しいです。 f.fields_forに変更すると、lab_suppliersフォームの値がlab_params内にネストされるようになりました – Michal

0

ワーキング解決策を見つけるために私を助けた他のポストへのリンク:I以下 [Rails nested form with multiple entries

は、ネストされた属性を選択し、複数の値を渡すとDBにそれらを挿入する方法を示す実用的なソリューションを提供します。

モデル

class Lab < ActiveRecord::Base 
    has_many :lab_suppliers#, :foreign_key => 'lab_id', dependent: :destroy 
    has_many :suppliers, through: :lab_suppliers 
    accepts_nested_attributes_for :lab_suppliers, :allow_destroy => true 
end 

class Supplier < ActiveRecord::Base 
    has_many :lab_suppliers 
    has_many :labs, through: :lab_suppliers 
end 

class LabSupplier < ActiveRecord::Base 
    belongs_to :lab 
    belongs_to :supplier 
end 

コメント: accepts_nested_attributes_forのみにhas_many/has_oneの側に置かれています。 belongs_toの側に

フォーム(ラボ)= F

<%= form_for(@lab) do |f| %> 
    <div class="field"> 
    <%= f.label :code %><br> 
    <%= f.text_field :code %> 
    </div> 
    <div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 
    <div class"field"> 
<%= f.fields_for :lab_suppliers do |ff| %> 
    <%= ff.label :supplier_id %><br> 
    <%= ff.collection_select :supplier_id, Supplier.all, :id, :name, {include_blank: true}, {:multiple => true, :class=>""} %> 
<% end %> 

<%それを置く必要はありません。提出%> <%エンド%>

コントローラ

コメント:SUPPLIER_ID::[]内

class LabsController < ApplicationController 
    before_action :set_lab, only: [:show, :edit, :update, :destroy] 

def new 
    @lab = Lab.new 
    @lab.lab_suppliers.build 
end 


def create 
    @lab = Lab.new(lab_params) 

@startcount=1 #start counting from 1 because the first element in the array of nested params is always null 
@lab.lab_suppliers.each do |m| 
    #raise lab_params[:lab_suppliers_attributes]["0"][:supplier_id][@startcount].inspect 
    m.supplier_id = lab_params[:lab_suppliers_attributes]["0"][:supplier_id][@startcount] 
    @startcount +=1 
end 

respond_to do |format| 
    if @lab.save 
    lab_params[:lab_suppliers_attributes]["0"][:supplier_id].drop(@startcount).each do |m| 
     @lab.lab_suppliers.build(:supplier_id => lab_params[:lab_suppliers_attributes]["0"][:supplier_id][@startcount]).save 
     @startcount += 1 
    end 
    format.html { redirect_to labs_path, notice: 'Lab was successfully created.' } 
    format.json { render :show, status: :created, location: @lab } 
    else 
    format.html { render :new } 
    format.json { render json: @lab.errors, status: :unprocessable_entity } 
    end 
end 
end 


    private 

def lab_params 
    params.require(:lab).permit(:name, :code, lab_suppliers_attributes: [supplier_id: [] ]) 
end 
end 

コメントサプライヤーやlab_suppliersコントローラ内の任意の追加のparamsを許可する必要はありません lab_suppliers_attributes permitts複数のドロップダウンから値の配列を渡します

関連する問題