0

I have a vendor model, a product model, and a vendor_product model. In my vendors form, I have used nested form to create vendor_products with attributes as vendor_id, product_id and copies.On creating a new vendor, it also creates a vendor_product. But for some reason, it does not stores the vendor_id and product_id in vendor_products table but only stores the copies

My associations are as follows

A vendor ->

        has_many :vendor_products
        has_many :products, through: :vendor_products

A product ->

        has_many :vendor_products
        has_many :vendors, through: :vendor_products

A vendor_product

        belongs_to :vendor
        belongs_to :product

Vendor.rb

class Vendor < ActiveRecord::Base

  has_many :vendor_products
  has_many :products, through: :vendor_products
  accepts_nested_attributes_for :vendor_products, :products, 
 :allow_destroy => true

end

My vendors/_form.html.erb

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

  <ul>
  <% @vendor.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>
    :
    :
    :
 <%= f.fields_for :vendor_products do |vproducts| %>
  <div class="field">
  <%= vproducts.label :product %><br>
    <%= collection_select(:product, :product_ids, Product.all, :id,
    :product_name,
             {:prompt => 'Please select', :multiple => true }) %>
  </div>
  <div class="field">
    <%= vproducts.label :copies %><br>
    <%= vproducts.number_field :copies %>
  </div>
  <% end %>

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

My vendors_controller.rb

class VendorsController < ApplicationController
      before_action :set_vendor, only: [:show, :edit, :update, :destroy]
      respond_to :json

      def index
        @vendors = Vendor.all.limit(20)
      end


      def show 
      end 


      def new 
        @vendor = Vendor.new
        @vendor.products.build
        @vendor.vendor_products.build
      end


      def edit
      end


      def create
        @vendor = Vendor.new(vendor_params)      

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


     def update
        respond_to do |format|
        if @vendor.update(vendor_params)
           format.html { redirect_to @vendor, notice: 'Vendor was successfully 
      updated.' }
           format.json { render :show, status: :ok, location: @vendor }
        else
          format.html { render :edit }
          format.json { render json: @vendor.errors, status: 
     :unprocessable_entity }
        end
      end
    end



      private

      def set_vendor
        @vendor = Vendor.find(params[:id])
      end

      def vendor_params
         params.require(:vendor).permit(:name, :email, :phone_no, :addressline1, 
      :addressline2, :landmark,
      :city, :state, :country, :pincode, :latitude, :longitude, :status, 
        product_attributes: [:product_id, :product_name, :price ], 
        vendor_products: [:vendor_product_id, :vendor_id, :product_id, 
        :copies])
      end
    end

Now a vendor and VendorProduct is created but my vendor_product looks lik this

    {"id":3,
     "vendor_id":null,
     "product_id":null,
     "copies":4,
    }

Can any one point out how to fix this. What am I doing wrong. Please bear in mind that I am a rails newbie.

2 Answers 2

1
change once vendor_products to vendor_products_attributes and look

In your view

<%= collection_select(:product, :product_ids, Product.all, :id,
    :product_name,
             {:prompt => 'Please select', :multiple => true }) %>

replace with 

<%= vproducts.select :product_id, options_from_collection_for_select(Product.all, "id", "name"), prompt: "Select something" %>
Sign up to request clarification or add additional context in comments.

3 Comments

Well it populated the vendor_id for now, but the product_id still shows null.Any thing else which is wrong with my controller logic?
Well that seems to mess up the collection select.It shows an empty collection select with all the product names listed as plain text below the collection select
Yes, That did the trick, all my fields are now getting populated. Thank you
0

Change this line:

<%= collection_select(:product, :product_ids, Product.all, :id,
    :product_name,
             {:prompt => 'Please select', :multiple => true }) %>
  </div>

to

<%= collection_select(:product, :product_id, Product.all, :id,
    :product_name,
             {:prompt => 'Please select', :multiple => true }) %>
  </div>

1 Comment

I have tried what you mentioned. However it yields same results. Creates a vendor_product with empty vendor_id and product_id.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.