In rails console & using the models below, I connected grades K
, 1
, and 2
to the school whose Edit form has this select field:
As you can see, that association correctly selects the 3 items in the field, but if I click to select/deselect grades, those changes aren't getting saved.
Here are the models:
# app/models/school.rb
class School < ActiveRecord::Base
has_many :grades_schools, inverse_of: :school
has_many :grades, through: :grades_schools
accepts_nested_attributes_for :grades_schools, allow_destroy: true
end
# app/models/grades_school.rb
class GradesSchool < ActiveRecord::Base
belongs_to :school
belongs_to :grade
end
# app/models/grade.rb
class Grade < ActiveRecord::Base
has_many :grades_schools, inverse_of: :grade
has_many :schools, through: :grades_schools
end
The form looks like this:
# app/views/schools/_form.html.haml
= form_for(@school) do |f|
/ <snip> other fields
= collection_select(:school, :grade_ids, @all_grades, :id, :name, {:selected => @school.grade_ids, include_hidden: false}, {:multiple => true})
/ <snip> other fields + submit button
And the controller looks like this:
# app/controllers/schools_controller.rb
class SchoolsController < ApplicationController
before_action :set_school, only: [:show, :edit, :update]
def index
@schools = School.all
end
def show
end
def new
@school = School.new
@all_grades = Grade.all
@grades_schools = @school.grades_schools.build
end
def edit
@all_grades = Grade.all
@grades_schools = @school.grades_schools.build
end
def create
@school = School.new(school_params)
respond_to do |format|
if @school.save
format.html { redirect_to @school, notice: 'School was successfully created.' }
format.json { render :show, status: :created, location: @school }
else
format.html { render :new }
format.json { render json: @school.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @school.update(school_params)
format.html { redirect_to @school, notice: 'School was successfully updated.' }
format.json { render :show, status: :ok, location: @school }
else
format.html { render :edit }
format.json { render json: @school.errors, status: :unprocessable_entity }
end
end
end
private
def set_school
@school = School.find(params[:id])
end
def school_params
params.require(:school).permit(:name, :date, :school_id, grades_attributes: [:id])
end
end
I have a feeling that the crux of my problem has to do with a mismatch between the params generated by collection_select
and the strong parameters. One or both of these is probably incorrect, but I can't for the life of me find example code online that shows me what I'm doing wrong.
After trying a load of failed variations, I'm at my wits end! Thanks in advance for your help!
Crap. I could have sworn I tried this before, but it must have been when using fields_for
in the form instead of collection_select
. The solution:
def school_params
params.require(:school).permit(:name, :date, :school_id, grades_attributes: [:id])
end
becomes
def school_params
params.require(:school).permit(:name, :date, :school_id, grade_ids: [])
end
I'm still curious how it would work when using fields_for @grades_schools
, but will have to save that investigation for another day....