Rails创建has_and_belongs_to_many复选框

时间:2018-02-21 21:38:11

标签: ruby-on-rails postgresql rails-activerecord has-and-belongs-to-many jointable

我正在尝试以has_and_belongs_to_many关系保存复选框选择。我想将每个street链接到找到它的maps。在map表中,复选框列表显示在新视图或编辑视图中。但我错过了把这一切联系在一起的东西。似乎地图列表应该与每个街道项目一起保存,但我不知道如何做到这一点。为此,我有一个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

联接表的迁移:

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

没有错误,但没有保存。我真的不明白应该保存在哪里以及如何保存。我在references表中创建了一个名为Streets的字段,但没有对此进行引用。它似乎不应该保存在maps_streets表中,而不是。

我认为有更强大的has_manybelongs_to关系,但我认为我不会需要它,也看不出它会有什么帮助。

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

1 个答案:

答案 0 :(得分:1)

我认为你只需要做一些改变。

在您的Controller中,将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 %>