醫生可以在許多醫院執行手術。請求參數過濾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"
}
那麼是怎麼回事?我假設params
從request.params
獲取其數據,那爲什麼它會丟失hospital_ids
?
@doctor.update(doctor_params)
顯然不是與任何醫院更新模型。
任何想法?
哇!這完全是它。我已經把頭髮拉出了幾個小時,謝謝你。 – trainface