HABTM协会建设

时间:2014-06-25 15:41:00

标签: ruby-on-rails ruby-on-rails-4 has-and-belongs-to-many

我需要在:departaments_products表中传播这些值:但是我收到了错误: 我正在使用Rails 4

NoMethodError in Products#new
undefined method `departament_id' for #<Product:0x007f916d35d648>

view.html.erb

<%= form_for(@product) do |f| %>
  <% if @product.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@product.errors.count, "error") %> prohibited this product from being saved:</h2>

      <ul>
      <% @product.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :price %><br>
    <%= f.text_field :price %>
  </div>
    <%= f.collection_select(:departament_id, Departament.all, :id, :name, {:include_blank => true}) %>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Products_controller:

class ProductsController < ApplicationController
  before_action :set_product, only: [:show, :edit, :update, :destroy]

  # GET /products
  # GET /products.json
  def index
    @products = Product.all
  end

  # GET /products/1
  # GET /products/1.json
  def show
    @product = Product.find( params[:id] )

  end

  # GET /products/new
  def new
    @product = Product.new
  end

  # GET /products/1/edit
  def edit
  end

  # POST /products
  # POST /products.json
  def create
    @product = Product.new(product_params)

    respond_to do |format|
      if @product.save

        format.html { redirect_to @product, notice: 'Produto criado com sucesso' }
        format.json { render :show, status: :created, location: @product }
      else
        format.html { render :new }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /products/1
  # PATCH/PUT /products/1.json
  def update
    respond_to do |format|
      if @product.update(product_params)
        format.html { redirect_to @product, notice: 'Product was successfully updated.' }
        format.json { render :show, status: :ok, location: @product }
      else
        format.html { render :edit }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /products/1
  # DELETE /products/1.json
  def destroy
    @product.destroy
    respond_to do |format|
      format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_product
      @product = Product.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def product_params
      params.require(:product).permit(:name, :price)

    end
end

模型

class Departament < ActiveRecord::Base
  has_and_belongs_to_many :products
end

class Product < ActiveRecord::Base
  has_and_belongs_to_many :departaments
end

移植

class AddProductsAndDepartaments < ActiveRecord::Migration
  def change
    create_table :departaments_products do |t|
      t.references :product, :departament
    end

  end
end

2 个答案:

答案 0 :(得分:1)

尝试使用departament_ids

对于has_many =&gt; departament_ids

对于has_one =&gt; departament_id

答案 1 :(得分:1)

作为HABTM协会,从逻辑上讲,您应该为单个产品选择多个departament_ids。也就是说,您应在{1}} multiple: true中添加collection_select选项,以便在您的视图代码中departament_ids(注意 departament_ids 复数):

<%= f.collection_select(:departament_ids, Departament.all, :id, :name, {include_blank: true}, {multiple: true}) %>

目前,您正在以departament_id访问它(注意单数)但是根据HABTM关联,您会得到一个名为departament_ids的方法(注意复数)和NOT departament_id这就是您收到NoMethodError in Products#new undefined method 'departament_id'

错误的原因

完成此更改后,您需要允许departament_ids中的ProductsController字段,如下所示:

def product_params
  params.require(:product).permit(:name, :price, :departament_ids => [])
end
使用

:departament_ids => []是因为departament_ids允许多次选择,因此您在表单提交时会在Array哈希中将其作为params收到。