4

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
1
  • doesn't active model serialization gem cover this? Commented Jan 10, 2017 at 4:49

5 Answers 5

15

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\"}]}"
Sign up to request clarification or add additional context in comments.

8 Comments

this does not work. It just adds another root language and it display as {"language":[{"language":{"created_at":null,"id":1,"language":"English","updated_at":null}},{"language":{"created_at":null,"id":2,"language":"Swedish","updated_at":null}}]}
The "languages:" key should not appear if you include the :root => false option (that's what it's for, see the docs). I added another root "language" because that's what you wanted.
I saw the docs that you mentioned and you were right but do not know why this is not working. But any way thankyou so much for the response. May be it can work for some others so i will mark your answer as accepted. In case you find some other reason please tell me.
Is it possible that your Language model overrides as_json somewhere? Do you use any gems that might modify it? That's the only possibility I can think of.
I have used "ActiveRecord.Base.include_root_in_json = false" in my language.rb file and now the root disappears but this makes the root disappear for all the methods that were used in the language_controller file.
|
3

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

Comments

2

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

Comments

1

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"
         }
  }],
}

Comments

0

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

1 Comment

Also check it's usage if you miss one here it is - fabrik42.github.com/acts_as_api

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.