3
votes

I have a model for languages and i want to get all the languages as json but the json output looks as follows

[{"language":{"created_at":null,"id":1,"language":"English","updated_at":null}},{"language":{"created_at":null,"id":2,"language":"Swedish","updated_at":null}},{"language":{"created_at":null,"id":3,"language":"German","updated_at":null}},{"language":{"created_at":null,"id":4,"language":"French","updated_at":null}},{"language":{"created_at":null,"id":5,"language":"spanish","updated_at":null}},{"language":{"created_at":null,"id":6,"language":"dutch","updated_at":null}},{"language":{"created_at":"2012-12-03T05:01:18Z","id":7,"language":"Tamil","updated_at":"2012-12-03T05:01:18Z"}}]

but i want to make this as

{"language":[{"created_at":null,"id":1,"language":"English","updated_at":null},{"created_at":null,"id":2,"language":"Swedish","updated_at":null},{"created_at":null,"id":3,"language":"German","updated_at":null},{"created_at":null,"id":4,"language":"French","updated_at":null},{"created_at":null,"id":5,"language":"spanish","updated_at":null},{"created_at":null,"id":6,"language":"dutch","updated_at":null},{"created_at":null,"id":7,"language":"Tamil","updated_at":null} ] }

Update

def index
 @languages = Language.all
 respond_to do |format|
   format.json { render json: @languages}
 end
end

update 2

    class Language < ActiveRecord::Base
        ActiveRecord::Base.include_root_in_json = false
        has_and_belongs_to_many :users 
    end
5
doesn't active model serialization gem cover this?BenKoshy

5 Answers

15
votes

I believe this should work:

format.json { render json: { "language" => @languages.as_json(:root => false) }.to_json }

What this does it to convert the @languages array into an array of JSON-formatted hash models with no root keys (using as_json), then wraps the result in a hash with a root key "language", and convert that hash into a JSON-formatted string with to_json. (See the docs for details on including or not including a root node using as_json.)

For example, with a model Post:

posts = Post.all
#=> [#<Post id: 1, name: "foo", title: "jkl", content: "some content", created_at: "2012-11-22 01:05:46", updated_at: "2012-11-22 01:05:46">]

# convert to array of hashes with no root keys
posts.as_json(root: false)
#=> [{"content"=>"some content", "created_at"=>Thu, 22 Nov 2012 01:05:46 UTC +00:00, "id"=>1, "name"=>"foo", "title"=>"jkl", "updated_at"=>Thu, 22 Nov 2012 01:05:46 UTC +00:00}]

# add root back to collection:
{ "post" => posts.as_json(root: false) }
#=> {"post"=>[{"content"=>"some content", "created_at"=>Thu, 22 Nov 2012 01:05:46 UTC +00:00, "id"=>1, "name"=>"foo", "title"=>"jkl", "updated_at"=>Mon, 03 Dec 2012 09:41:42 UTC +00:00}]}

# convert to JSON-formatted string
{ "post" => posts.as_json(root: false) }.to_json    
#=> "{\"post\":[{\"content\":\"some content\",\"created_at\":\"2012-11-22T01:05:46Z\",\"id\":1,\"name\":\"foo\",\"title\":\"jkl\",\"updated_at\":\"2012-12-03T09:43:37Z\"}]}"
3
votes

override the as_json on the Model you want to customize

def as_json options={}
    {
      id: id,
      login: login, 
      name: custom.value, #for custom name
     ...
    }
end

==> or

def as_json(options={})
  super(:only => [:id, :login, :name ....])
end

from : here

Other link: here

2
votes

I suggest you to use rabl gem (https://github.com/nesquena/rabl) to format your data.

0
votes

The easiest way of adding custom json output when you render json is by using gem that provide many json templates-

https://github.com/fabrik42/acts_as_api

0
votes

Override as_json method in your model, to include associations, hide columns and why not? calling custom methods as they were attributes

  def as_json(options={})
    super(:except => [:created_at,:updated_at],
          :include => { 
            :members => {
                :only => [:role, :account], 
                :include => {
                  :account => {
                    :only => [:name, :subdomain]
                  }
                }
              }
            },
          :methods => [:jwt_token]
    )
  end

This will output something like this:

{
  "id": 2,
  "name": "Test Teacher",
  "email": "[email protected]",
  "jwt_token":"eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MiwiZXhwIjoxNTY2NzQ0OTQzfQ.HDGu7JiJEQEEpGo7inuXtOZBVQOfTaFquy8dr-QH5jY",

  "members": [{
        "role": "instructor",
        "account": {
            "name": "Testing",
            "subdomain": "test"
         }
  }],
}