2014-01-21 1 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» и нашел запись, и все это хорошо.

Но посмотрите на врача param! ->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), очевидно, не обновляет модель с больницами.

Любые идеи?

ответ

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

Смежные вопросы