Mahesh Mesta
Mahesh Mesta

Reputation: 783

Has_many through associated json data sent through postman not getting populated in the database in rails 4

I am trying to make a Post request through Postman which send my vendor model attributes and values and vendor_products model attributes.My json data looks like this

  {
   "name": "Raghu",
   "email": "[email protected]",
   "phone": "9008849042",
     :
     :
   "vendor_products_attributes":
      {
        [{"product_id" : 7, "copies" : 8},
         {"product_id" : 8, "copies" : 10}]
      }
    }

Now all my vendor model fields get populated, but vendor_products models are not been populated.I have used a nested form and nested attributes for vendors and vendor_products

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>
<%= vproducts.select :product_id, 
options_from_collection_for_select(Product.all, "id", "product_name"),    
prompt: "Select something" %>
<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
    @product = @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_attributes: [:vendor_product_id, :vendor_id, 
    :product_id, 
    :copies])
  end
 end

routes.rb

  Rails.application.routes.draw do

  match '/vendors/create_vendor' => 'vendors#create' , via: [:post]

    resources :vendor_products
    resources :products
    resources :vendors      
  end

My server logs

Started POST "/vendors/create_vendor" for 127.0.0.1 at 2016-07-29    
15:03:43 +0530
Processing by VendorsController#create as */*
Parameters: {"name"=>"Ragtyh", "email"=>"[email protected]", 
"phone_no"=>"9008849042", "addressline1"=>"#7, Varsha Pg", 
"addressline2"=>"23rd main marenhalli, JP nagar 2nd phase", 
"landmark"=>"opp mayura sweets", "city"=>"Bangalore", 
"state"=>"Karnataka", "country"=>"India", "pincode"=>"560078", 
"latitude"=>12.898773, "longitude"=>77.5764094, "status"=>true, 
"vendor_products_attributes"=>[{"product_id"=>9, "copies"=>2}, 
{"product_id"=>7, "copies"=>3}], "vendor"=>{"name"=>"Ragtyh", 
"email"=>"[email protected]", "phone_no"=>"9008849042", 
"addressline1"=>"#7, Varsha Pg", "addressline2"=>"23rd main marenhalli, 
JP nagar 2nd phase", "landmark"=>"opp mayura sweets", 
"city"=>"Bangalore", "state"=>"Karnataka", "country"=>"India", 
"latitude"=>12.898773, "longitude"=>77.5764094, "status"=>true, 
"pincode"=>"560078"}}
 [1m[35m (0.2ms)[0m  BEGIN
 [1m[36mSQL (0.5ms)[0m  [1mINSERT INTO "vendors" ("name", "email", 
"phone_no", "addressline1", "addressline2", "landmark", "city", "state", 
"country", "pincode", "latitude", "longitude", "status", "created_at", 
"updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, 
$13, $14, $15) RETURNING "id"[0m  [["name", "Ragtyh"], ["email", 
"[email protected]"], ["phone_no", "9008849042"], ["addressline1", 
"#7, Varsha Pg"], ["addressline2", "23rd main marenhalli, JP nagar 2nd 
phase"], ["landmark", "opp mayura sweets"], ["city", "Bangalore"], 
["state", "Karnataka"], ["country", "India"], ["pincode", "560078"], 
["latitude", 12.898773], ["longitude", 77.5764094], ["status", "t"], 
["created_at", "2016-07-29 09:33:48.844763"], ["updated_at", "2016-07-29 
09:33:48.844763"]]
 [1m[35m (0.7ms)[0m  COMMIT
 Redirected to http://localhost:3000/vendors/100025 
 Completed 302 Found in 5592ms (ActiveRecord: 1.4ms)

While the raw json data in postman populates the vendor table, the vendor_products are not populating or been created. How can I solve this.Please note that I am a rails newbie

Upvotes: 0

Views: 273

Answers (1)

Sravan
Sravan

Reputation: 18647

Gone through your code and all your code is correct, but the issue seems to be there in the request you are making to the controller through the postman.

In the request json file you do-not have the vendor key at all, so as you can see your logs, the vendor_products are not inside the vendor hash.

"vendor_products_attributes"=>[{"product_id"=>9, "copies"=>2}, {"product_id"=>7, "copies"=>3}]

this should ne inside the vendor hash,

So your JSON should look something like this,

{
"vendor": {
   "name": "Raghu",
   "email": "[email protected]",
   "phone": "9008849042",
     :
     :
   "vendor_products_attributes":
      {
        [{"product_id" : 7, "copies" : 8},
         {"product_id" : 8, "copies" : 10}]
      }
    }
  } 

To achive this, you should take some thing like,

  vendor[:name] = ""
  vendor[:name] = ""
  vendor[:phone] = ""
  ...

  ...
  vendor[:vendor_products_attributes][product_id][] = 7
  vendor[:vendor_products_attributes][copies][] = 10
  vendor[:vendor_products_attributes][product_id][] = 8
  vendor[:vendor_products_attributes][copies][] = 15

from your postnam.

Upvotes: 1

Related Questions