Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selective deep rendering of hasMany relationships in grails

For the following domain model:

class Route {
    String  name
    static  hasMany     = [checkPoints:CheckPoint]  
    static  belongsTo   = [someBigObject:SomeBigObject]


    static mapping = {
        checkPoints lazy: false
    }
}

I need to return a specific Route as a JSON from a web service. And I want this JSON to contain all the checkPoints but no other compositions (i.e.:someBigObject).

If I do

def route = Route.findById(id)
render route as JSON

all I got is the id's of the checkPoints, no other field is fetched:

{
    "class": "com.example.Route",
    "id": 1,
    "checkPoints": [
        {
            "class": "CheckPoint",
            "id": 1
        },
        {
            "class": "CheckPoint",
            "id": 2
        },
        {
            "class": "CheckPoint",
            "id": 4
        },
        {
            "class": "CheckPoint",
            "id": 3
        }
    ],
    "someBigObject": {
        "class": "SomeBigObject",
        "id": 2
    }
}

but if I do

JSON.use('deep') {
    render route as JSON
}

I get everything. I mean, almost all the database is getting fetched through various relationships.

Is there way to do this without creating the jsonMaps manually?

like image 982
Bahadır Yağan Avatar asked Jan 31 '13 12:01

Bahadır Yağan


1 Answers

You can register your own JSON marshaller for chosen classes and return properties which you want to render. Map can be done automatically by iteration over class fields. Marshaller ca be registered for example in bootstrap or in domain class during creation.

JSON.registerObjectMarshaller(Route) {
    return [name:it.name, checkPoints:it.checkPoints]
}

There is nice article about it under: http://manbuildswebsite.com/2010/02/15/rendering-json-in-grails-part-3-customise-your-json-with-object-marshallers/

Hope it helps

like image 179
droggo Avatar answered Nov 05 '22 00:11

droggo