1

I have two rails models:

A Milestone has many Tasks A Task belongs to a Milestone

In my controller I call the following:

@milestones = Milestone.all
render :json => @milestones.to_json(:include => :tasks)

Which gives me:

[   {
    "id": 5,
    "name": "This is milestone #1",
    "tasks": [{
            "complete": false,
            "id": 60,
            "name": "aaaaa",
            "milestone_id": 5,
        }, {
            "complete": false,
            "id": 62,
            "name": "ccccc",
            "milestone_id": 5,
        }
    ]
}, {
    "id": 6,
    "name": "This is milestone #2",
    "tasks": [{
            "complete": false,
            "id": 65,
            "name": "ffffff",
            "milestone_id": 5,
        }, {
            "complete": false,
            "id": 66,
            "name": "gggggg",
            "milestone_id": 5,
        }
    ]
}

]

But I need to be able to easily navigate through the JSON, so I'd like to be able to format it like this (notice each "sub array" is labeled with "milestone_ID" or "task_ID"):

[   
"milestone_5": {
    "id": 5,
    "name": "This is milestone #1",
    "tasks": [
        "task_60":{
            "complete": false,
            "id": 60,
            "name": "aaaaa",
            "milestone_id": 5,
        }, 
        "task_62":{
            "complete": false,
            "id": 62,
            "name": "ccccc",
            "milestone_id": 5,
        }
    ]
}, 

"milestone_6":{
    "id": 6,
    "name": "This is milestone #2",
    "tasks": [
        "task_65":{
            "complete": false,
            "id": 65,
            "name": "ffffff",
            "milestone_id": 5,
        }, 
        "task_66":{
            "complete": false,
            "id": 66,
            "name": "gggggg",
            "milestone_id": 5,
        }
    ]
}

]

Does anybody have any idea how to get Rails to custom format JSON. Even if I have to lose the "milestone_" part and just spit out the ID, that would be very helpful.

Thanks!

2
  • Is there a specific reason you need it to be "milestone_6" instead of an array of milestones? Your output appears to defeat a lot of the purpose of json. Why does each key need to include the id if you already have it in the set of values? Commented May 3, 2013 at 21:20
  • Including the id in the key will allow me to navigate through the nested json a bit easier. I have to do a lot of replacing/updating because I'm using a front-end MVC. Commented May 4, 2013 at 16:48

1 Answer 1

3

Take a look at the json_builder gem.

What you're asking is certainly doable, but personally when you start doing anything remotely useful with json output from controllers, the default to_json method becomes unwieldy. It's best to explicitly output exactly what you want the json to look like.

Specifically in your json_builder file...

milestone.json.json_builder

@milestones.each do |milestone|
  key "milestone_#{milestone.id}" do
    id milestone.id
    name milestone.name
  end
end

etc etc. I believe that would do the trick.

Edit: I tend to only include the exact fields from the model that I need for whatever resource is consuming my json. This will improve performance and can make things easier to debug when something goes wrong. It's also very obvious which fields are going to show up where.

Sign up to request clarification or add additional context in comments.

1 Comment

Exactly what I'm looking for! And yes, I planed to only include the handful of fields I need, as the JSON could become very long, very fast.

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.