How to display attributes of object when using jbuilder? - ruby-on-rails

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

Related

Nested json object with Jbuilder

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

Get nested Arrays in JSON

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

Jbuilder Partials Merge Instead of Nest

I'm attempting to have a json response that looks like the below:
{
id: 3,
title: "Magic",
desc: "A bag of coolness!"
type: {
id: 14,
title: "Dust"
}
}
What I get is:
{
id:14,
title:"Dust",
desc:"A bag of coolness!"
type: null
}
The three jbuilder files being used are below:
_item.json.jbuilder
json.(item, :id, :title, :desc)
json.type json.partial! item.type
show.json.jbuilder
json.partial! #item
_type.json.jbuilder
json.(type, :id, :title)
Why is jbuilder merging type and item instead of nesting type? How do I prevent this?
To nest a partial, the below code will work:
json.type do
json.partial! item.type
end

Rabl for a nested hash of ActiveRecord collections

I have a few ActiveRecord objects like City, Country, State etc. My controller action is like (as a representative example):
def get_data
#data = {
cities: City.limit(2),
countries: Country.limit(2),
states: State.limit(2),
version: 1000
}
respond_with #data
end
I want to render a JSON like:
{
data: {
country: [{id: 1, name: 'a'}, {id: 2, name: 'b'}],
state: [{id: 1, name: 'p'}, {id: 2, name: 'q'}],
city: [{id: 1, name: 'x'}, {id: 2, name: 'y'}],
version: 1000
}
}
(Please note singular keys for collections, Please do not suggest changes to the JSON structure, as it is fixed.)
What should be the rabl template for this? I have been breaking my head on this for hours.
if i were you i will not even care to go to rabl template for this because what your are creating with this code:
#data = {
cities: City.limit(2),
countries: Country.limit(2),
states: State.limit(2),
version: 1000
}
is the final output , not the individual components.
you can just replace this with:
render :json => {
:data => {
cities: City.limit(2).map{ |c|{:id => c[:id] },
countries: Country.limit(2).map{ |c|{:id => c[:id] },
states: State.limit(2).map{ |c|{:id => c[:id] },
version: 1000
}
}
its not a best use case for rabl , but if you still want it to load via rabl this below code in the get_data.json.rabl will do just fine.
node :data do
{
:version_number => #data[:version_number],
:country => #data[:countries].map{ |c|{:id => c[:id] , :name => c[:name]} }
:state => #data[:states].map{ |s|{:id => s[:id] , :name => s[:name]} }
:city => #data[:city].map{ |c|{:id => c[:id] , :name => c[:name]} }
}
end

Rails Creating a Valid JSON object

I could use your helping creating a valid JSON object in Rails.
Here is an example of a valid JSON object that I'm using in the jQuery plugin: https://drew.tenderapp.com/kb/autosuggest-jquery-plugin
var data = {items: [
{value: "21", name: "Mick Jagger"},
{value: "43", name: "Johnny Storm"},
{value: "46", name: "Richard Hatch"},
{value: "54", name: "Kelly Slater"},
{value: "55", name: "Rudy Hamilton"},
{value: "79", name: "Michael Jordan"}]};
Within Rails I'm creating my object as follows:
#projects = Projects.all
#projectlist = Array.new
#projectlist << {
:items => #projects.map { |project|
{
:name => space.name,
:value => space.id
}
}
}
But this ends up outputting like so which ERRORs by the plugin:
[{"items":[{"value":74,"name":"XXXXXX"},{"value":71,"name":"XXXXXX"},{"value":70,"name":"XXXXXX"}]}]
Looks like there is a [] around the initial {} any idea why that's happening and how to build a valid JSON object?
Thanks!
Simply assign #projectlist to a Hash, like so:
EDIT After looking at the plugin's API, I've come to the conclusion that you need to convert your values to strings first:
#projects = Projects.all
#projectlist = {
:items => #projects.map { |project|
{
:name => space.name,
:value => space.id.to_s
}
}
}
Since you're initializing #projectlist to an Array and pushing the Hash onto it, you're getting those wrapping [] characters.

Resources