Reputation: 523
I have a model named User
, and I'm getting all Users with User.all.as_json
.
The User
model also has values of first_name
and last_name
, so my result would look something like this:
[
{
"username"=>"johndoe",
"first_name"=>"John",
"last_name"=>"Doe"
},
{
"username"=>"test",
"first_name"=>"Test",
"last_name"=>"Number 1"
}
]
I want to add a custom value to each Hash in the array that looks like this:
[
{
"username"=>"johndoe",
"first_name"=>"John",
"last_name"=>"Doe",
"full_name"=>"John Doe"
},
{
"username"=>"test",
"first_name"=>"Test",
"last_name"=>"Number 1",
"full_name"=>"Test Number 1"
}
]
full_name
is not a model field, but instead a method of get_full_name
. I don't know how to merge that key-value in each hash. This didn't work:
posts = Post.all.as_json.each do |post|
post.merge({:full_name => post.get_full_name})
end
It returns the original result without the full_name
value.
Upvotes: 1
Views: 3763
Reputation: 593
as_json supports :methods key, you can do it like this:
post.as_json( methods: :full_name )
also it might be delivered to the relations as well like:
post.as_json( methods: [:full_name, :cool_name], include: { avatar: { methods: :url } } )
Upvotes: 1
Reputation: 56
you can write as_json method in model and include method name as below
for example in you post model you can write like this
def as_json(options = {})
super(:only => [:username, :first_name, :last_name],
:methods => [:full_name])
end
def full_name
"#{first_name} #{last_name}"
end
Upvotes: 1
Reputation: 14610
You might also consider a serializer if this is not just a one-off thing:
The serializer would be a separate class that formats your data that way you want and would look something like (from railscasts by Ryan Bates):
class PostSerializer < ActiveModel::Serializer
def full_name
end
end
http://railscasts.com/episodes/409-active-model-serializers
Upvotes: 1
Reputation: 1517
The code Post.all.as_json
returns an array of hashes, with string keys. So you can't use the method get_full_name on the hash object.
You should convert your data to a hash inside your loop, and use a map
instead of a each
to keep your changes.
posts = Post.all.map do |post|
post.as_json.merge({:full_name => post.get_full_name})
end
To get your full_name
as a string key, you can use a string in your hash, instead of a symbol.
post.as_json.merge({"full_name" => post.get_full_name})
Upvotes: 5