0

중첩 된 폼과 has_many 관계에 문제가 있습니다. 사례 : 실험실과 그 공급자가 있습니다. 공급자는 실험실간에 공유 할 수 있습니다.레일 4 네스트 된 폼 has_many, through 및 multiple select

모델

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 

결과 R 제출 양식 :

매개 변수 : 양식을 제출

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

동안 내가 ActiveModel :: ForbiddenAttributesError 가 줄에 나타납니다

내가 예상대로 작동하도록 실종 무엇
@lab_supplier = @lab.lab_suppliers.new(params[:lab_suppliers]) 

?

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

이 그것을 시도하고 알려 : 당신이 명시 적으로 같은 통과해야 lab_suppliers에서 속성 lab_params 말할 필요 같은

답변

1

보인다. 작업 해결책을 찾기 위해 나에게 도움을 다른 게시물에 대한

+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은 여러의 값은 중첩 된 속성을 선택하고 DB에 삽입 전달하는 방법을 보여주는 작업 솔루션을 제공 아래 Rails nested form with multiple entries

.

모델

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 측

양식 (랩)

<%= 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 %> 

<% = F를 넣어 없음.제출 %> <퍼센트 끝 %>

컨트롤러

코멘트 : 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는 다중 드롭 다운의 값 배열을 전달합니다