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
Related
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 started to learn how to use Grape. I have collection with a lot of attributes and want only some of them. I did something like this:
get :all_elements do
[
my_collection.each do |element|
{
id: element.id,
name: element.name
}
end
]
end
However this is not working. How can I create custom json array from collection?
Please try this code.
list = my_collection.map do |element|
{ :id => element.id,
:name => element.email
}
end
list.to_json
I have a dilema. There's a huge function in my controller to standardise loads of different types of data into one list for the view. So I have this kind of way of handling it at the moment:
customer.notes.each do |note|
to_push = {
id: note.id,
title: 'Contact Note',
type: 'note',
description: note.notes,
user: note.user,
date: note.date,
action: nil,
extras: note.customer_interests,
closed: false,
colour: '#9b59b6'
}
history.push to_push
end
I want to move that out of the controller into the model but I'm not too sure how. I ideally want a method like customer.notes.format_for_timeline but I can't figure out how to iterate over results like that in a self method within the class.
Thanks
I found out how. Using a self method then all:
def self.format
all.each do |item|
# Manipulate items here
end
end
However, I ended up having a method like this:
def format
{
id: id,
note: 'Contact Note',
# Etc
}
end
Then just used:
customer.notes.map {|i| i.format }
I am trying Rabl, however, I seem to receive a practically empty json block.
require_dependency "api/application_controller"
module Api
class RentablePropertiesController < ApplicationController
respond_to :json
def index
#r = Core::RentableProperty.all
# render :text => #r.to_json --> note: this renders the json correctly
render "api/rentable_properties/index" #note: rabl here does not
end
end
end
index.json.rabl
collection #r
Output
[{"rentable_property":{}}]
Note: with a simply #r.to_json, it renders correctly:
[{"id":1,"description":"description","property_type_id":1,"created_at":"2013-08-22T19:04:35.000Z","updated_at":"2013-08-22T19:04:35.000Z","title":"Some Title","rooms":null,"amount":2000.0,"tenure":null}]
Any idea why rabl doesn't work?
The documentation of RABL (https://github.com/nesquena/rabl#overview) says that you need to precise what attributes you want to show in your JSON.
Their example:
# app/views/posts/index.rabl
collection #posts
attributes :id, :title, :subject
child(:user) { attributes :full_name }
node(:read) { |post| post.read_by?(#user) }
Which would output the following JSON or XML when visiting /posts.json:
[{ "post" :
{
"id" : 5, title: "...", subject: "...",
"user" : { full_name : "..." },
"read" : true
}
}]
I have this rabl template:
object #photo
attributes :id
child :comments do
attributes :id, :body
end
Which gives me this JSON response:
{
photo: {
id: 1,
comments: [
{
comment: {
id: 1,
body: 'some comment'
}
},
{
comment: {
id: 2,
body: 'another comment'
}
}
]
}
}
But I want it to look like this:
{
id: 1,
comments: [
{
id: 1,
body: 'some comment'
},
{
id: 2,
body: 'another comment'
}
]
}
Why does rabl wrap each element in the array with an extra object called comment. In this way when I access the collection in javascript I have to write:
var comment = image.comments[0].comment
instead of:
var comment = image.comments[0]
I know that if I include :comments in the attributes list for the #photo object it works the way I want, but when I want another level of nested associations for each comment object, there isn't a way to handle that besides using child, but that gives me the JSON response that I don't want.
Maybe I'm just misunderstanding the whole thing -- can someone explain or help? Thanks!
Got it!
Create a new file in config/initializers/rabl_config.rb:
Rabl.configure do |config|
config.include_json_root = false
config.include_child_root = false
end