Reputation: 783
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
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