Rails 创建 has_and_belongs_to_many 复选框

Rails creating has_and_belongs_to_many checkbox

我正在尝试以 has_and_belongs_to_many 关系保存复选框选择。我想 link 每个 street 到它所在的 maps。在 map table 中,复选框列表显示在新视图或编辑视图中。但是我在 link 中遗漏了一些东西。似乎地图列表应该与每个街道项目一起保存,但我不知道该怎么做。为此,我有一个 map 字段 references

未经验证的模型:

class Street < ApplicationRecord
  has_and_belongs_to_many :maps
end

class Map < ApplicationRecord
  has_and_belongs_to_many :streets
end

streets_controller.rb(相关部分):

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

新建和编辑视图模板的相关部分:

<%= 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%>

生成的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

加入的迁移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

没有错误,但没有保存任何内容。而且我真的不明白应该在哪里以及如何保存它。我在 Streets table 中创建了一个名为 references 的字段,但没有对此的引用。它似乎不应该保存在 maps_streets table 中,但事实并非如此。

我考虑过建立更稳固的 has_manybelongs_to 关系,但我认为我不需要它,也看不出它会有什么帮助。

参数? "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"} 选中一个复选框

我认为您只需要进行一些更改。

在您的控制器中,将 map_ids 添加到允许的参数中。

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, :notes, :map_ids => [])
  end

在您的表单中,collection_check_boxes 应该是:map_ids

<%= form_with(model: @street, local: true) do |form| %> 

  <%= form.collection_check_boxes( :map_ids, @maps, :id, :name, bootstrap: {check_inline: true}, class: "") do |b|
      b.label(:"data-value" => b.value) { b.check_box + b.text }
  <% end %>

<% end %>