What I want:
{
status: 200,
response:
{
user: { id: 1, name: 'Bob', city: 'New York' }
}
}
What I have tried:
json.status 200
json.user json.(#user, :id, :name, :city)
But it does not give the desired results:
{
"status" : "200"
"response" : "{"status":200,"id":1, name: "bob", city: "New York","user":["id","name","city"]}"
}
What am I doing wrong?
Try this:
json.status 200
json.response do
json.user #user.as_json(only: [:id, :name, :city])
end
Related
I didn't find any examples of how to use rswag to generate documentation according to json api.
spec/integration/pets_spec.rb
require 'swagger_helper'
It is possible to change the code to generate the format of json api?
describe 'Pets API' do
path '/api/v1/pets' do
post 'Creates a pet' do
tags 'Pets'
consumes 'application/json', 'application/xml'
parameter name: :pet, in: :body, schema: {
type: :object,
properties: {
name: { type: :string },
photo_url: { type: :string },
status: { type: :string }
},
required: [ 'name', 'status' ]
}
response '201', 'pet created' do
let(:pet) { { name: 'Dodo', status: 'available' } }
run_test!
end
response '422', 'invalid request' do
let(:pet) { { name: 'foo' } }
run_test!
end
end
end
path '/api/v1/pets/{id}' do
get 'Retrieves a pet' do
tags 'Pets'
produces 'application/json', 'application/xml'
parameter name: :id, :in => :path, :type => :string
response '200', 'name found' do
schema type: :object,
properties: {
id: { type: :integer, },
name: { type: :string },
photo_url: { type: :string },
status: { type: :string }
},
required: [ 'id', 'name', 'status' ]
let(:id) { Pet.create(name: 'foo', status: 'bar', photo_url: 'http://example.com/avatar.jpg').id }
run_test!
end
response '404', 'pet not found' do
let(:id) { 'invalid' }
run_test!
end
end
end
end
If rswag what tips would you give me?
You need to change the swagger_helper.rb file. Change the file format to JSON. I have attached the screenshot for that one below:
https://i.stack.imgur.com/MzOR9.png
In my acceptance test, I want to test the value of gift.available_quantity which is virtual attribute:
def available_quantity
pendings_orders = Order.where(status: 'pending')
order_lines_pending = OrderLine.where(order_id: pendings_orders)
gift_quantity_pending = order_lines_pending.sum do |oline|
return oline.quantity if oline.gift_ean13 == ean13
end
quantity - gift_quantity_pending
end
I don't test my code, but it's not the problem.
The problem is that my rspec evaluate the value of my gift.available_quantity before creating my fake order:
require 'acceptance_helper'
resource 'Gifts' do
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
header 'Authorization', :authorization
get '/api/v1/gifts' do
let!(:member) { create(:member, id: 1) }
let(:user) { create(:user, :activated, member: member) }
let(:token) { Knock::AuthToken.new(payload: { sub: user.id }).token }
let(:authorization) { "Bearer #{token}" }
let!(:delivery_address) { create(:delivery_address, :favorited, member: member) }
let!(:gifts) { create_list(:gift, 2, :enabled, quantity: 4) }
let(:order_lines) { create(:order_line, gift_ean13: gifts.first.ean13, quantity: 1, order_id: order.id) }
let(:order_lines2) { create(:order_line, gift_ean13: gifts.last.ean13, quantity: 2, order_id: order.id) }
let!(:order) { create(:order, member: member, delivery_address: delivery_address) }
example_request 'Get gift list' do
expected_response = {
gifts: [
{
id: gifts.first.id,
name: gifts.first.name,
description: gifts.first.description,
reward_price: gifts.first.reward_price,
quantity: gifts.first.quantity,
date_from: gifts.first.date_from,
date_to: gifts.first.date_to,
image: nil,
quantity_alert: gifts.first.quantity_alert,
available_quantity: 3
},
{
id: gifts.last.id,
name: gifts.last.name,
description: gifts.last.description,
reward_price: gifts.last.reward_price,
quantity: gifts.last.quantity,
date_from: gifts.last.date_from,
date_to: gifts.last.date_to,
image: nil,
quantity_alert: gifts.last.quantity_alert,
available_quantity: 2
}
]
}
expect(status).to eq(200)
expect(response_body).to eq(expected_response.to_json)
end
end
end
My order isn't created before, so gift.avalaible_quantity isn't good...
Can someone help me understand "RSpec flow"?
I think the problem is that your order_lines aren't being created before the spec runs.
Use let! to create them instead so they exist when the available_quantity method runs.
let!(:order_lines) { create(:order_line, gift_ean13: gifts.first.ean13, quantity: 1, order_id: order.id) }
let!(:order_lines2) { create(:order_line, gift_ean13: gifts.last.ean13, quantity: 2, order_id: order.id) }
I want to show an employee, and all of their reports like the following:
{
name :'ceo'
salary: '1000000'
directs:
{
name: 'sally',
salary: '100000'
},
{
name: 'phil',
salary: '100000'
}
}
I must have a defect such that I only get everything under directs. Here's the jbuilder code for the show action:
json.extract! #employee, :name, :salary
json.array! #employee.direct_reports do |d|
json.name d.name
json.salary d.salary
end
I've tried several iterations of the first part of the code, but I continually see the following on a rest call, for example http://localhost:3000/employees/1.json:
[
{
name: 'sally',
salary: '100000'
},
{
name: 'phil',
salary: '100000'
}
]
Make sure you have respond_to :json inside the respective controller and you have set #employee variable right.
Also try stopping and starting the rails application.
Check out this jbuilder snippet:
json.extract! #employee, :name, :salary
json.directs #employee.direct_reports do |d|
json.name d.name
json.salary d.salary
end
to get this:
{
name :'ceo'
salary: '1000000'
directs:
{
name: 'sally',
salary: '100000'
},
{
name: 'phil',
salary: '100000'
}
}
you need
json.extract! #employee, :name, :salary
json.name :name
json.salary :salary
json.array! #employee.direct_reports do |d|
json.name d.name
json.salary d.salary
end
I have an object (Institution) and I want to get the 2 arrays (marks and attachments) that are relationed with this object using JSON.
To be clear: For 1 institution, I have 3 marks and for every mark I have an attachment.
Here's my code of JSON file:
if #data['admin_institution']
json.extract! #data['admin_institution'], :id, :name, :phone, :address, :site, :created_at, :updated_at
if #data['admin_institution'].marks
json.marks #data['admin_institution'].marks
json.array!(#data['admin_institution'].marks) do | admin_mark|
json.attachment admin_mark.attachment
end
end
else
json.set! :response do
json.set! :error, 'Not Found!'
end
end
I want to reproduce something like this:
{
id: 14,
name: "Ins3",
phone: "793215-2555",
address: "lreewrwklkr",
site: "lkerlke.com",
created_at: "2016-03-01T14:00:37.000-03:00",
updated_at: "2016-03-01T14:00:37.000-03:00",
- marks: [
- {
id: 17,
admin_attachment_id: 927,
admin_bookmark_id: 3,
admin_institution_id: 14,
created_at: "2016-03-01T14:00:37.000-03:00",
updated_at: "2016-03-01T14:00:37.000-03:00"
},
{
id: 18,
admin_attachment_id: 945,
admin_bookmark_id: 1,
admin_institution_id: 14,
created_at: "2016-03-01T14:00:37.000-03:00",
updated_at: "2016-03-01T14:00:37.000-03:00"
}
],
- attachment: {
id: 927,
name: "nature-16",
title: "Nature-16",
description: null,
mime_type: "image/jpeg",
url: "/uploads/nature-16.jpg",
created_at: "2016-02-29T09:21:09.000-03:00",
updated_at: "2016-02-29T09:21:09.000-03:00"
}
}
Instead, I'm getting only the values of the last array (attachment). Thanks in advance.
UPDATE:
I used through-association on my institution model then I could get the attachments "directly" through the marks, without do a loop of marks. The following code is giving me almost all that I want.
if #data['admin_institution']
json.extract! #data['admin_institution'], :id, :name, :phone, :address, :site, :created_at, :updated_at, :marks, :attachments
else
json.set! :response do
json.set! :error, 'Not Found!'
end
end
It's returning the Institution, the marks and the attachments, BUT not nested. I want marks inside the institution and attachments inside the marks. How can I make it work?
Try this:
if #data['admin_institution']
...
if #data['admin_institution'].marks
json.marks #data['admin_institution'].marks do | admin_mark|
json.attachment admin_mark.attachment
end
end
else
...
end
Here is my API post:
resource :service_requests do
get do
authenticate!
current_company.service_requests
end
params do
requires :service_request, type: Hash do
optional :prefix, type: String
requires :first_name, type: String
requires :last_name, type: String
requires :contact_email, type: String, regexp: User::EMAIL_REGEX
requires :telephone, type: String
end
end
post do
authenticate!
{ service_request: params[:service_request] }
end
end
Here is what my json post looks like:
{
'service_request': {
'first_name': 'Foo',
'last_name': 'Bar',
'contact_email': 'foo#bar.com',
'telephone': '111-111-1111'
}
}
The error I am receiving is:
ActionDispatch::ParamsParser::ParseError (795: unexpected token at '{
'service_request': {
'first_name': 'Foo',
'last_name': 'Bar',
'contact_email': 'foo#bar.com',
'telephone': '111-111-1111'
}
}'):
Not sure what I am doing wrong. Anyone see anything that stands out?
Use double quotes in your json:
{
"service_request": {
"first_name": "Foo",
"last_name": "Bar",
"contact_email": "foo#bar.com",
"telephone": "111-111-1111"
}
}