I'm trying to save checkbox selections in a has_and_belongs_to_many
relationship. I want to link each street
to the maps
that it is found on. From the map
table a list of checkboxes is shown on new or edit views. But I'm missing something in linking this all together. It seems like the list of maps should be saved with each street item, but I'm not figuring out how to do that. I have a map
field references
for that purpose.
Models without validations:
class Street < ApplicationRecord
has_and_belongs_to_many :maps
end
class Map < ApplicationRecord
has_and_belongs_to_many :streets
end
streets_controller.rb (relevant parts):
class StreetsController < ApplicationController
before_action :set_street, only: [:show, :edit, :update, :destroy]
def new
@street = Street.new
gon.streetExtentArray = @street.extent_array
@maps = Map.all.order(:year)
end
def edit
@maps = Map.all.order(:year)
gon.streetExtentArray = @street.extent_array
gon.streetExtentJson = @street.extent_json
end
def create
@street = Street.new(street_params)
respond_to do |format|
if @street.save
format.html { redirect_to @street, notice: "Street was successfully created. #{undo_link}" }
format.json { render :show, status: :created, location: @street }
else
format.html { render :new }
format.json { render json: @street.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @street.update(street_params)
format.html { redirect_to @street, notice: "Street was successfully updated. #{undo_link}" }
format.json { render :show, status: :ok, location: @street }
else
format.html { render :edit }
format.json { render json: @street.errors, status: :unprocessable_entity }
end
end
end
private
def street_params
params.require(:street).permit(:city, :previous_name, :current_name, :date_earliest, :date_latest, :cross_streets, :extent_json, :extent, :extent_length, :extent_array, :number_of_blocks, :references, :ref1, :ref2, :ref3, :notes, {:reference_ids => []})
end
end
Relevant part of the new and edit view template:
<%= form_with(model: @street, local: true) do |form| %>
<%= form.label "City" %>
<%= form.text_field :city, id: :street_city %>
</div>
< and many other fields >
<%= form.collection_check_boxes( :references, @maps, :id, :name, bootstrap: {check_inline: true}, class: "") do |b|
b.label(:"data-value" => b.value) { b.check_box + b.text }
end %>
<%= form.submit%>
The generated HTML:
<input type="hidden" name="street[map_ids][]" value="" />
<input type="checkbox" value="12" name="street[map_ids][]" id="street_map_ids_12" /><label for="street_map_ids_12">1857 Bancroft</label>
<input type="checkbox" value="7" name="street[map_ids][]" id="street_map_ids_7" /><label for="street_map_ids_7">1888 Sanborn</label>
and six more similar checkboxes
The migration for the join table:
class CreateJoinTableMapsStreets < ActiveRecord::Migration[5.1]
def change
create_join_table :maps, :streets do |t|
t.index [:map_id, :street_id]
t.index [:street_id, :map_id]
end
end
end
No errors, but nothing is saved. And I don't really understand where and how this should be saved. I've created a field named references
in the Streets
table, but there is no reference to this. And it doesn't seemed like it should be saved in the maps_streets
table and it's not.
I considered having the more robust has_many
and belongs_to
relationship, but I don't think I'm going to need it and can't see how it would help.
Params? "street"=>{"city"=>"Los Angeles", "previous_name"=>"3rd St", "current_name"=>"Miramar St. One block abandoned", "date_earliest"=>"1921", "date_latest"=>"", "cross_streets"=>"Miramar. And gone one block between Lucas and Bixel", "number_of_blocks"=>"2", "extent_length"=>"", "references"=>["", "7"], "ref1"=>"Baist 1921", "ref2"=>"", "ref3"=>"", "notes"=>"3rd was jogged south starting at Beaudry to what was Crown Hill at Huntley/Boylston", "extent_json"=>"{\"type\":\"LineString\",\"coordinates\":[[-118.26117539280003,34.05901974362122],[-118.2593849946753,34.05823410691563],[-118.25815599257271,34.05768101430694],[-118.25759459655055,34.05717191451128],[-118.25663111959356,34.05654339202722]]}", "extent_array"=>"[[34.05900599436149,-118.26117038726808],[34.057672720136964,-118.25815558433534],[34.057174959049995,-118.25757622718811],[34.0565527535807,-118.25666427612306]]"}, "commit"=>"Update Street", "controller"=>"streets", "action"=>"update", "id"=>"645"}
One checkbox checked