I'm having problems importing a .json file and saving the data inside it in the api database. My code is like this:
def create
content = JSON.parse(File.open(params[:products]).read)
#product = Product.new(content)
if #product.save
render json: { message: 'Produto Salvo', data: #product }, status: 200
else
render json: #product.errors, status: :unprocessable_entity
end
end
The file(products.json)contains this data:
[{
"title": "Brown eggs",
"type": "dairy",
"description": "Raw organic brown eggs in a basket",
"filename": "0.jpg",
"height": 600,
"width": 400,
"price": 28.1,
"rating": 4
}, {
"title": "Sweet fresh stawberry",
"type": "fruit",
"description": "Sweet fresh stawberry on the wooden table",
"filename": "1.jpg",
"height": 450,
"width": 299,
"price": 29.45,
"rating": 4
}]
By the time I implement the method, all fields are saved as NIL:
#<ActiveRecord::Relation [#<Product id: 3, title: nil, product_type: nil, description: nil, filename: nil, height: nil, width: nil, price: nil, rating: nil, created_at: "2021-11-10 14:15:11.261454000 +0000", updated_at: "2021-11-10 14:15:11.261454000 +0000">]>
How do I save with the data correctly filled in?
It looks like you're reading in an array of multiple products?
I would suggest inserting a binding.pry between where you set content and where you set #product
Paste the value of content here and I think the solution will become clear.
Related
I am using 'active_model_serializers', '~> 0.10.6' for rendering my API response. For my index action I am doing this -
render json: #items, root: 'data', each_serializer: ItemsSerializer
but in my response, I am not getting the root key - data
[
{
"id": 85,
"title": "B",
"source": "manager_added",
"shared": true,
"status": "suggested",
"item_type": "action_item",
"manager": {
"id": 2614,
"full_name": "Calvin H",
"first_name": "Calvin"
},
"reportee": {
"id": 2614,
"full_name": "Calvin H",
"first_name": "Calvin"
}
},
{
"id": 87,
"title": "D",
"source": "manager_added",
"shared": true,
"status": "suggested",
"item_type": "action_item",
"manager": {
"id": 2614,
"full_name": "Calvin H",
"first_name": "Calvin"
},
"reportee": {
"id": 2614,
"full_name": "Calvin H",
"first_name": "Calvin"
}
}
]
What I am doing wrong here?
The hardest part with AMS is finding it's right documentation. Based on the version you have mentioned, here's the documentation link:
https://github.com/rails-api/active_model_serializers/tree/0-10-stable/docs
There are 3 adapters:
:default (There won't be any root, basically root key is useless, even if you add it)
:json (This is what you need, you can add custom root key. https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/adapters.md#example-output-1)
:json_api (Default root key will be data, but you can customize, maybe you can use this, but it will change the whole structure of your response json into something like: https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/adapters.md#example-output-2)
Answer:
render json: #items, root: 'data', adapter: :json, each_serializer: ItemsSerializer
or
render json: #items, adapter: :json, each_serializer: ItemsSerializer
I am implementation of data from a JSON file to a Ruby on Rails application by using HTTparty gem, but I am getting Error no implicit conversion of String into Integer
I refered this tutorial link
My json data,
{
"restaurant_name": "Restaurant 3",
"address": "xyz address",
"country": "United States",
"currency": "USD",
"client_key": "12345",
"client_name": "Client 3",
"client_email": "test3#mail.com",
"client_phone": "9876",
"product_tier": "tier1",
"brand_logo_large": {
"ID": 37,
"id": 37,
"title": "bait-al-bahar-logo-design",
"filename": "bait-al-bahar-logo-design.png",
"filesize": 105071,
"url": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"link": "http://codekyt.in/froodle-wp/projects/res-1-client-1/bait-al-bahar-logo-design/",
"alt": "",
"author": "1",
"description": "",
"caption": "",
"name": "bait-al-bahar-logo-design",
"status": "inherit",
"uploaded_to": 35,
"date": "2019-01-04 11:11:48",
"modified": "2019-01-04 11:13:01",
"menu_order": 0,
"mime_type": "image/png",
"type": "image",
"subtype": "png",
"icon": "http://codekyt.in/froodle-wp/wp-includes/images/media/default.png",
"width": 600,
"height": 500,
"sizes": {
"thumbnail": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design-150x150.png",
"thumbnail-width": 150,
"thumbnail-height": 150,
"medium": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design-300x250.png",
"medium-width": 300,
"medium-height": 250,
"medium_large": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"medium_large-width": 600,
"medium_large-height": 500,
"large": "http://codekyt.in/froodle-wp/wp-content/uploads/2019/01/bait-al-bahar-logo-design.png",
"large-width": 600,
"large-height": 500
}
}
In model,
include HTTParty
In controller
def index
require 'httparty'
#category = HTTParty.get(
'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
:headers =>{'Content-Type' => 'application/json'}
)
end
In gemfile,
gem 'httparty'
gem 'json'
In view,
<%#category.each do |category|%>
<%=category["restaurant_name"]%>
<%=category["country"]%>
<%=category["currency"]%>
<%=category["usd"]%>
<%=category["client_key"]%>
<%=category["client_name"]%>
<%=category["client_email"]%>
<%=category["client_phone"]%>
<%=category["product_tier"]%>
<%=category["brand_logo_large"]%>
<%end%>
HTTParty.get returns an encapsulated response type of class HTTParty::Response, you need to retrieve the parsed response from that by:
response = HTTParty.get(
'http://codekyt.in/froodle-wp/wp-json/data/v2/projects?client_key=12345',
:headers =>{'Content-Type' => 'application/json'}
)
#category = response.parsed_response # this will return the json.
Also you do not need to iterate on #category in your case, the json object is singular and you can directly use it:
<%=#category["restaurant_name"]%>
<%=#category["country"]%>
<%=#category["currency"]%>
<%=#category["usd"]%>
<%=#category["client_key"]%>
<%=#category["client_name"]%>
<%=#category["client_email"]%>
<%=#category["client_phone"]%>
<%=#category["product_tier"]%>
<%=#category["brand_logo_large"]%>
Here it's my products.controller
def index
if params[:page]
#product = Product.page(params[:page]).per(5)
else
#product = Product.order('updated_at DESC')
end
render json: {
status: '200',
message: 'OK',
data: ActiveModel::Serializer::CollectionSerializer.new(#product, each_serializer: ProductSerializer)},status: 200
end
def show
render json: {
status: '200',
message: 'OK',
data: ActiveModel::Serializer::CollectionSerializer.new(#product, each_serializer: ProductSerializer)},status: 200
end
Here my product serializer
class ProductSerializer < AplicationSerializer
attributes :id, :product_name, :category, :company, :description, :logo_img, :web_link
belongs_to :category
has_many :images
en
d
If I try to access localhost:3000/products/, it can display all the data that I want, but if I want to try localhost:3000/products/1, it's wrong, so what the wrong about my code?
{
"status": "200",
"message": "OK",
"data": [
{
"id": 1,
"product_name": "MDS",
"category": {
"id": 4,
"category": "Market Place",
"created_at": "2018-04-12T02:58:59.949Z",
"updated_at": "2018-04-12T02:58:59.949Z"
},
"company": "PT Media Data ",
"description": "ISP di Indo",
"logo_img": "mds.jpg",
"web_link": "https://mds.co/",",
"images": [
{
"id": 1,
"link": "http:/mds.com/mds.png"
},
{
"id": 2,
"link": "http:/mds.com/mds.png"
},
{
"id": 3,
"link": "http:/mds.com/mds.png"
},
{
"id": 4,
"link": "http:/mds.com/mds.png"
}
]
}
]
}
in the above is the display I want to display at http://localhost:3000/products/1, but i still got no appear, even though i can display it with same code on def index
Thanks for your help
The only thing that can seem to be missing here is setting the #product
If you have a before_action :show, :set_product this might not be the problem.
The other difference is between an array in the index and a single element in the show. you better use ProductSerializer.new(#product).as_json instead of using the collection serializer
iam using active model serializers in my rails, this is my snippet
# GET /users
def index
#users = User.all
render json: {data: #users, status: httpstatus[:getSuccess]}
# render json: {data: #users, status: httpstatus[:getSuccess]}
end
but its showing like this in postman
"data": [
{
"id": 38,
"name": "tyasa",
"age": 21,
"created_at": "2017-05-30T06:23:03.504Z",
"updated_at": "2017-05-30T06:23:03.504Z"
},
{
"id": 39,
"name": "wahyu",
"age": 21,
"created_at": "2017-05-30T06:23:37.359Z",
"updated_at": "2017-05-30T06:23:37.359Z"
},]
but its work when just render the #users
# GET /users
def index
#users = User.all
render json: {data: #users, status: httpstatus[:getSuccess]}
# render json: #users
end
i just wanna delete created at and update at from the json.
How to solve this..
sory bad english
I just wanna delete created at and update at from the json.
You can use except option of as_json
render json: {data: #users.as_json(:except => [:created_at, :updated_at]), status: httpstatus[:getSuccess]}
which should give you
"data": [
{
"id": 38,
"name": "tyasa",
"age": 21
},
{
"id": 39,
"name": "wahyu",
"age": 21
},]
I'm rendering json without object title. So I tried to render it as text as follows
render :text=>
[{
"id": "0",
"heading": "Trending this Week",
"title": "Prost Brew Pub",
"place": "Sholinganallur",
"image": "http://192.168.0.103/test2/blur.jpg",
"rating": 4.3,
"amount": "Rs. 1800 for two people",
"review": "320 Reviews",
"photos": "630 Photos",
"genre": ["British", "Mexican", "Continental"]
},...
It convert the above as following
[{:id=>"0", :heading=>"Trending this Week", :title=>"Prost Brew Pub", :place=>"Sholinganallur", :image=>"http://192.168.0.103/test2/blur.jpg", :rating=>4.3, :amount=>"Rs. 1800 for two people", :review=>"320 Reviews", :photos=>"630 Photos", :genre=>["British", "Mexican", "Continental"]}
why did it convert the "id": "0" to :id=>"0" ?
How can I render the above array without any change? thanks in advance.
Is there and render method available to get the object without it's title?
Your ":text" is an array is of Hashes. So Ruby is rendering it in Hash syntax. If you want json you should render json not text.
render json: #object, status: :ok