2017-08-12 88 views
0

好吧我已经尝试了一切我知道自定义呈现与JSON视图的一对多关联,并失败惨败。Grails 3 JSON视图自定义渲染一对多关联

这里是我的机票域的一部分,看起来像(全好这里)...

class TttTicket { 

    String title 
    String number 
    String description 
    TttUser assignee 
    String priority 
    String status 
    TttUser creator 


    Date dateCreated 
    Date lastUpdated 

    static mappedBy = [subscribers : 'none', creator:'none'] 

    static belongsTo = [project:TttProject, creator:TttUser] 
    static hasMany = [subscribers: TttUser] 

... blar blar 
} 

这里是我的相关GSON呈现模板...

import ttt_api_server.TttTicket 

model { 
    TttTicket tttTicket 
} 

json g.render(tttTicket, [excludes:['creator','subscribers','project']]){ 
    creator { 
     id tttTicket.creator.id 
     name tttTicket.creator.name 
     email tttTicket.creator.email 
    } 

    project{ 
     id tttTicket.project.id 
     name tttTicket.project.name 
    } 
} 

...这是工作很好,迄今。我想现在限制每个用户的属性输出。

如何旋转这些?例如...

import ttt_api_server.TttTicket 

model { 
    TttTicket tttTicket 
} 

json g.render(tttTicket, [excludes:['creator','subscribers','project']]){ 
    creator { 
     id tttTicket.creator.id 
     name tttTicket.creator.name 
     email tttTicket.creator.email 
    } 
    subscibers g.render(){ 
     tttTicket.subscribers.each {sub -> 
      return { 
       name sub.name 
      } 
     } 
    } 
    project{ 
     id tttTicket.project.id 
     name tttTicket.project.name 
    } 
} 

这似乎没有记录在任何地方。我想控制这个级别的每个用户的JSON输出。不在域级别,因为根据我的JSON要求,我可能需要更改属性输出。

请帮助:-(

+0

顺便说一句 - 我已经建立了一个临时解决方案,其中只包括我需要在订户类上通过它的gson的属性,但这不是渴望d效果。我希望能够在直接对订阅者进行其他调用时保留所有属性,但在对具有多个订阅者的票据进行休息调用时限制属性 – AndyRED

回答

1

如果我理解正确此,当你做机票REST调用,你想那是的hasMany关系来显示指定的属性里面的域对象(在这种情况下,它的用户)。但是当你直接在用户打电话,你想所有属性

可以先创建地图,然后根据所创建的地图上渲染的对象(看看this) 你的情况。:

import ttt_api_server.TttTicket 

model { 
    TttTicket tttTicket 
} 

json g.render(tttTicket, [excludes:['creator','subscribers','project']]){ 
    creator { 
     id tttTicket.creator.id 
     name tttTicket.creator.name 
     email tttTicket.creator.email 
    } 

    def s = tttTicket.subsribers.collect { 
     [ 
      id: it.id, 
      name: it.name 
     ] 
    } 

    subscribers s //this part is doing the rendering 

    project{ 
     id tttTicket.project.id 
     name tttTicket.project.name 
    } 
} 
0

如果这是你想要的,只要它呈现为JSON要呈现此对象的方式,我建议实施ObjectMarshaller<JSON>

class TttTicketMarshaller implements ObjectMarshaller<JSON> { 

    @Override 
    boolean supports(Object object) { 
    return object instanceof TttTicket 
    } 

    @Override 
    void marshalObject(Object object, JSON converter) throws ConverterException { 
    TttTicket ticket = (TttTicket)object 

    def jsonWriter = converter.writer 
    jsonWriter.object() 
    jsonWriter.key("title") 
    jsonWriter.value(ticket.title) 

    //other fields 

    jsonWriter.key("creator") 
    jsonWriter.object() 
    jsonWriter.key("id") 
    jsonWriter.value(ticket.creator.id) 

    //other creator fields 
    jsonWriter.endObject() 
    } 
} 

我不是100%肯定的object()endObject()功能,但看起来是正确的用法。

一旦你有了这个,你BootStrap.groovy注册这样的:在地方

def init = { servletContext -> 
    JSON.registerObjectMarshaller(new TttTicketMarshaller()) 
} 

有了这一切,你可以简单地使用

render myTicket as JSON 

所界定返回对象的JSON表示你的编组