如何在 Rails 上的 Ruby 中保存多对多

How to save a many-to-many in Ruby on Rails

我有一个多对多关系,在创建或编辑时 rails 都没有保存它。我使用复选框控件来获得多对多关系。

基本上,当用户创建 "Shop" 时,它将具有商店所属类别的复选框(餐厅、汉堡店、披萨制造商)。因此,用户将选中 select 这些类别的复选框。

我没有收到任何错误,操作已完成。商店已创建,但关系未保存在数据库中。

如果我尝试编辑这家商店,关系不存在。

这是我的模特:

class Shop < ActiveRecord::Base
  belongs_to :locale
  has_many :shop_categorizations
  has_many :shops_categories, through: :shop_categorizations
  has_many :shop_hours
  has_attached_file :image, :default_url => "/assets/default_image.png", :storage => :s3,
      :s3_credentials => Rails.root.join("config/s3_credentials.yml"),
      :path => ":style/shop/:id",
      :url => ":s3_domain_url"
  validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
end


class ShopsCategory < ActiveRecord::Base
  has_many :shop_categorizations
  has_many :shops, through: :shop_categorizations
end


class ShopCategorization < ActiveRecord::Base
  belongs_to :shop
  belongs_to :shops_category
end

这是处理我的代码的控制器:

   class ShopsController < ApplicationController
  before_action :set_shop, only: [:show, :edit, :update, :destroy]

  def new
    @shop = Shop.new
  end

def create
    @shop = Shop.new(shop_params)

    respond_to do |format|
      if @shop.save
        format.html { redirect_to @shop, notice: 'Shop was successfully created.' }
        format.json { render :show, status: :created, location: @shop }
      else
        format.html { render :new }
        format.json { render json: @shop.errors, status: :unprocessable_entity }
      end
    end
  end

  def shop_params
      params.require(:shop).permit(:company_name, :fantasy_name, :cnpj, :locale_id, :street_name, :number, :neighborwood, :complement, :login, :password, :phone1, :phone2, :flag_open, :flag_card, :flag_delivery, :price_delivery, :image)
    end

我的simple_form是这样准备的:

<%= simple_form_for(@shop) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :company_name %>
    <%= f.input :fantasy_name %>
    <%= f.input :cnpj %>
    <%= f.association :locale, :label_method => :city %>
    <br>
    <%= f.association :shops_categories, as: :check_boxes, :label_method => :name, :input_html => { :class => 'check'} %>
    <br>
    <%= f.input :street_name %>
    <%= f.input :number %>
    <%= f.input :neighborwood %>
    <%= f.input :complement %>
    <%= f.input :login %>
    <%= f.input :password %>
    <%= f.input :phone1 %>
    <%= f.input :phone2 %>
    <%= f.input :flag_open %>
    <%= f.input :flag_card %>
    <%= f.input :flag_delivery %>
    <%= f.input :price_delivery %>

    <%= f.input :image, as: :file %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

是的,就像 Alex 在他的评论中提到的那样,您的 shop_params 应该如下所示:

def shop_params
  params.require(:shop).permit(:company_name, :fantasy_name, :cnpj, :locale_id, :street_name, :number, :neighborwood, :complement, :login, :password, :phone1, :phone2, :flag_open, :flag_card, :flag_delivery, :price_delivery, :image, shops_category_ids: [])
end

请注意,新添加的 shops_category_ids 是一个数组,以允许 ids 的数组来自您的

<%= f.association :shops_categories, as: :check_boxes, :label_method => :name, :input_html => { :class => 'check'} %>

在表格中。