2014-01-21 75 views
2

醫生可以在許多醫院執行手術。請求參數過濾HABTM模型關係的更新行爲

class Doctor < ActiveRecord::Base 
    has_and_belongs_to_many :hospitals 
end 

醫院可以有許多醫生在其中進行手術。

class Hospital < ActiveRecord::Base 
    has_and_belongs_to_many :doctors 
end 

新的連接表遷移看起來像這樣。

class CreateDoctorsHospitals < ActiveRecord::Migration 
    def change 
    create_table :doctors_hospitals, id: false do |t| 
     t.belongs_to :doctor 
     t.belongs_to :hospital 

     t.timestamps 
    end 
    end 
end 

我們想更新@doctor對象,並給它一些醫院。

<%= form_for(@doctor) do |f| %> 
<%= f.label :notes %><br> 
<%= f.text_area :notes %><br> 
<%= f.label :hospitals %><br> 
<%= f.collection_select :hospital_ids, Hospital.all, :id, :name, {}, { multiple: true } %><br> 
<%= f.submit %> 
<% end %> 

生成的HTML看起來像這樣。

<form accept-charset="UTF-8" action="/doctors/1" class="edit_doctor" id="edit_doctor_1" method="post"> 
    <div> 
    <input name="utf8" type="hidden" value="✓"> 
    <input name="_method" type="hidden" value="patch"> 
    <input name="authenticity_token" type="hidden" value="xxx"> 
    </div> 
    <label for="doctor_notes">Notes</label><br> 
    <textarea id="doctor_notes" name="doctor[notes]"></textarea><br> 
    <label class="control-label" for="doctor_hospitals">Hospitals</label><br> 
    <input name="doctor[hospital_ids][]" type="hidden" value=""> 
    <select class="form-control" id="doctor_hospital_ids" multiple="multiple" name="doctor[hospital_ids][]"> 
     <option value="1">First Hospital</option> 
     <option value="2">Second Hospital</option> 
     ... 
     <option value="n">Nth Hospital</option 
    </select> 
    <input name="commit" type="submit" value="Update Doctor"> 
</form> 

DoctorsController的相關代碼片段在這裏。

class DoctorsController < ApplicationController 
    before_action :set_doctor, only: [:show, :edit, :update, :destroy] 

    def update 
    respond_to do |format| 
     if @doctor.update(doctor_params) 
     format.html { redirect_to edit_doctor_hospitals_path, notice: 'Doctor was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: 'edit' } 
     format.json { render json: @doctor.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    def set_doctor 
    @doctor = Doctor.find(params[:id]) 
    end 

    def doctor_params 
    params.require(:doctor).permit(:first_name, :last_name, :email, :status, :notes, :hospital_ids) 
    end 
end 

雖然在Update方法中,@doctor已定:set_doctor已經一把抓起難以捉摸「params」醫生的ID,找到了記錄,這一切都很好。

但看看醫生的參數! - >params[:doctor]=>{"notes"=>"Here be notes"}hospital_ids在哪裏?下面是params樣子:

{ 
    "utf8"=>"✓", 
    "_method"=>"patch", 
    "authenticity_token"=>"xxx", 
    "doctor"=>{ 
    "notes"=>"Here be notes" 
    }, 
    "commit"=>"Update Doctor", 
    "action"=>"update", 
    "controller"=>"doctors", 
    "id"=>"1" 
} 

如果我們看看request.params在這個非常同一時刻,我們將看到它包括hospital_ids!精彩!

{ 
    "utf8"=>"✓", 
    "_method"=>"patch", 
    "authenticity_token"=>"xxx", 
    "doctor"=>{ 
    "notes"=>"Here be notes", 
    "hospital_ids"=>["", "1", "4", "10"] # I don't know what that blank one is for, but whatever. 
    }, 
    "commit"=>"Update Doctor", 
    "action"=>"update", 
    "controller"=>"doctors", 
    "id"=>"1" 
} 

那麼是怎麼回事?我假設paramsrequest.params獲取其數據,那爲什麼它會丟失hospital_ids

@doctor.update(doctor_params)顯然不是與任何醫院更新模型。

任何想法?

回答

1

對於HABTM,使用要求PARAMS這樣的:

def doctor_params 
    params.require(:doctor).permit(:first_name, :last_name, :email, :status, :notes, {:hospital_ids => []}) 
    end 

參考 - https://coderwall.com/p/_1oejq

+0

哇!這完全是它。我已經把頭髮拉出了幾個小時,謝謝你。 – trainface