I am working on this code:
render json: User.find(params[:id]).to_json(
:include =>
{
:user_quests => { :inlcude => { :quest }, :only => { :id } },
:user_skills
},
:except =>
{
:authentication_token,
:email
}
)
It results in a SyntaxError. The only working code I currently have is:
render json: User.find(params[:id]).to_json(
:include =>
[
:user_quests,
:user_skills
],
:except =>
[
:authentication_token,
:email
]
)
But I need to pass further parameters to only one of the associations to perform a nested include. The other one (:user_skills) should be fetched the same way as in the working code. How do I do that?
This code results in a syntax error, because you don't use collections properly. An array ([]) is a list of values, whereas a hashmap (or simply hash, {}) requires key-value pairs.
In to_json's context an array of associations:
[
:user_quests,
:user_skills
]
...is roughly equivalent to a hash of associations mapped to empty option hashes:
{
:user_quests => {},
:user_skills => {}
}
Having performed that transformation, you can selectively add options wherever you like.
Here it is solution which works for me and is compatible with Rails 4:
render json: User.find(params[:id]).as_json(
include:
{
user_quests:
{
include:
{
quest:
{
only: :_id
}
}
},
user_skills:
{
}
},
except: [:authentication_token, :email]
)
Related
In my application, :foos have many :bars, and I'm serializing each foo as JSON like so:
#foo.as_json(
except: [:created_at, :updated_at],
include: {
bars: { only: [:ip_addr, :active] }
}
)
This gives me the following:
{
"id" => 2,
"name" => "Hello World",
"bars" => [
{ "ip_addr" => "192.123.12.32", "active" => 0 },
{ "ip_addr" => "192.123.12.33", "active" => 1 }
]
}
As you can see, my serialized hash includes an inactive bar. How can I exclude inactive bars from my hash?
It would be great if I could do this:
include: { bars: { only: { :active => true }}}
Have I taken as_json as far as it will go? Do I need to switch to active model serializers now?
I think you could try add some method like active_bars which will return exactly what you need like:
def active_bars
bars.where active: true
end
or you could even add new relation:
has_many :active_bars, -> { where active: true }, class_name: '..', foreign_id: '..'
and then you will be able write:
#foo.as_json(
except: [:created_at, :updated_at],
include: {
active_bars: { only: [:ip_addr, :active] }
}
)
you use as_json with conditions for customize json response for some actions, but model serializers for default json response that you needed for the most responses.
Read these Model_Serializer VS. as_json, record-serializers-from-scratch.
this function works. However, instead of including all the rounds. I just need to include the last one. How would I do it? I looked into using :scope but haven't found anything useful. Please help, it's driving me nuts!
def get_games_list
Rails.logger.info("get_games_list".colorize(:color => :white, :background => :blue))
player_1_games = Game.includes(:rounds, :player_2).where(:player_1_id => params[:player_id], :is_valid => true)
player_2_games = Game.includes(:rounds, :player_1).where(:player_2_id => params[:player_id], :is_valid => true)
render json: {
error_code: ERROR_NOERROR,
status: "ok",
player_1_games: player_1_games.as_json(
:include => {
:player_2 => {
:only => [:id, :user_name]
},
:rounds => {
:only => [:id, :playing_player_id]
}
}
),
player_2_games: player_2_games.as_json(
:include => {
:player_1 => {
:only => [:id, :user_name]
},
:rounds => {
:only => [:id, :playing_player_id]
}
}
)
}
return
end
You could create a :last_round has_one association in the Game model.
class Game < ApplicationModel
# ...
has_one :last_round, -> { order(round_date: :desc) }, class_name: 'Round'
# ...
end
I just implemented acts_as_taggable_on in my app and now I'm trying to trim my JSON response so it doesn't return everything for the Model in question. Here's what my as_json method looks like:
def as_json(options={})
super(:only => [:serial_number],
:include => {
:device_functions => { :only => [:can_scan, :can_brute] },
:scan_options => { :methods => :scan_ip_list}
}
)
end
Which currently returns:
{
"serial_number": "abcdefg12345",
"device_functions": [
{
"can_scan": true
}
],
"scan_options": [
{
"id": 1,
"device_id": 11,
"created_at": "2016-02-05T02:26:26.090Z",
"updated_at": "2016-02-05T02:26:26.090Z",
"scan_ip_list": [
"10.10.10.100-110",
"10.10.10.1"
]
}
]
}
I want to get rid of extra data that I don't need, such as id, device_id, created_at and updated_at now.
Also, using :only => worked find for the :device_functions response, but I had to use :methods => for :scan_options since I'm using acts_as_taggable_on... at least that's what I read and was the only option that returned something (I tried :only => and :include => as well but they returned an empty hash:
{
"serial_number": "abcdefg12345",
"device_functions": [
{
"can_scan": true
}
],
"scan_options": [
{}
]
}
You just need to add the :only option to your :scan_options hash too:
# ...
:scan_options => { :methods => :scan_ip_list, :only => :scan_ip_list }
Also, FWIW, you should probably merge into option in case you ever want to supply some of your own options, so:
# ...
super options.merge( :only => ...etc.
In my application, :foos have many :bars, and I'm serializing each foo as JSON like so:
#foo.as_json(
except: [:created_at, :updated_at],
include: {
bars: { only: [:ip_addr, :active] }
}
)
This gives me the following:
{
"id" => 2,
"name" => "Hello World",
"bars" => [
{ "ip_addr" => "192.123.12.32", "active" => 0 },
{ "ip_addr" => "192.123.12.33", "active" => 1 }
]
}
As you can see, my serialized hash includes an inactive bar. How can I exclude inactive bars from my hash?
It would be great if I could do this:
include: { bars: { only: { :active => true }}}
Have I taken as_json as far as it will go? Do I need to switch to active model serializers now?
I think you could try add some method like active_bars which will return exactly what you need like:
def active_bars
bars.where active: true
end
or you could even add new relation:
has_many :active_bars, -> { where active: true }, class_name: '..', foreign_id: '..'
and then you will be able write:
#foo.as_json(
except: [:created_at, :updated_at],
include: {
active_bars: { only: [:ip_addr, :active] }
}
)
you use as_json with conditions for customize json response for some actions, but model serializers for default json response that you needed for the most responses.
Read these Model_Serializer VS. as_json, record-serializers-from-scratch.
im trying to add some methods inside some includes with as_json in rails, but the second includes with method doesnt shows on the json. this is the code
format.json { render :json => { :projects => #projects.as_json(:include => [
:retail,
:property => {:methods => :name},
:user => {:methods => [:name, :address] } ] ) } }
and this is the json generated:
{"projects":[{"comment":null,"contractor":1,"created_at":"2013-10-17T16:57:36Z","id":5,"property_id":3,"retail_id":1,"updated_at":"2013-10-17T16:57:36Z","user_id":2,"retail":{"address":null,"created_at":"2013-10-16T22:29:38Z","id":1,"name":"asdasdsa","phone":"6677969224","property_id":null,"social_reason_id":null,"updated_at":"2013-10-17T17:18:09Z","web":"www.boxie.io"},"property":{"city":"Culiacan","colony":"Fracc Los Sauces","coordinates":"(24.7802016, -107.34894730000002)","country_id":1,"created_at":"2013-10-17T00:56:32Z","external_number":null,"id":3,"internal_number":2848,"population":null,"state_id":4,"street":"Alame\u00f1a","updated_at":"2013-10-17T00:56:32Z","zipcode":8028,"name":"Calle Alame\u00f1a, Fracc Los Sauces, 8028, Culiacan, Campeche Mexico"}}]}
as you can see the user information doesn't appear on the json.
Thank you
You didn't wrap them correctly, Your second and third child association should be hashes.
#projects.as_json(:include => [
:retail,
{ :property => {:methods => :name } },
{ :user => {:methods => [:name, :address] } }
]