医生可以在许多医院进行手术。
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
在更新方法中,@doctor
已设置:set_doctor
已从难以捉摸的“params
”中获取了医生的ID并找到了记录,这一切都很好。
但是看看医生的参数!! - &GT; 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)
显然没有更新任何医院的模型。
有什么想法吗?
答案 0 :(得分:1)
对于HABTM,请使用如下所示的参数:
def doctor_params
params.require(:doctor).permit(:first_name, :last_name, :email, :status, :notes, {:hospital_ids => []})
end