Rigo
Rigo

Reputation: 523

How to merge a value to a Rails query as_json

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

Answers (4)

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

Manju Sagar
Manju Sagar

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

pixelearth
pixelearth

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

Lasse Sviland
Lasse Sviland

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

Related Questions