One common scenario is that you have nested domain classes. In my case, I have a Show class. A Show is basically a TV series like Lost or Deperate Housewives. Each Show has a list of Season's. These seasons are strictly in order, like Lost has Season 1, 2, 3, 4 and 5 so far. Each Season has a number of Episode's, which are also stricly ordered. Then finally each Episode can be aired in different formats like HDTV, 720p or Standard. This makes up a nice class hierarchie having 1:n relations.
class Show {
String name
static hasMany = [ seasons : Season ]
static mapping = {
table 'ct_show'
}
static constraints = {
name(size:1..100,blank:false)
}
}
class Season {
Integer seasonNumber
static hasMany = [ episodes : Episode ]
static mapping = {
table 'ct_season'
}
static constraints = {
seasonNumber(size:1..100,blank:false)
}
}
class Episode {
Integer episodeNumber
static hasMany = [ formats : Format ]
static mapping = {
table 'ct_episode'
}
static constraints = {
episodeNumber(size:1..100,blank:false)
}
}
class Format {
String name
static mapping = {
table 'ct_format'
}
static constraints = {
name(size:1..100,blank:false)
}
}
Now I had a typical use case, that when you want to use Ajax within you web application, you want the Controller classes to return you domain objects as JSON. In Grails this is easy to accomplish, just read this example. However, I had the big problem that my domain class hierarchy heavily uses nested collections. This will not work when you just do this:
render Season.get(1) as JSON
In this blog post, the last example offers a solution to my problem but it is a rather static example. The idea is to use my root object (Season in my particular case) to produce a JSON string in the format I want and then return it via render as JSON. Building up this String would be quite a big chunk of code in Java probably involving StringBuilder, but Groovy has this great method .collect for Collections. Here is the Groovy code. Try this in Java.
def selectedSeason = Season.get(1)
def seasonJSON = [
id: selectedSeason.id,
seasonNumber: selectedSeason.seasonNumber,
episodes: selectedSeason.episodes.collect{
[
id: it.id,
episodeNumber: it.episodeNumber,
formats: it.formats.collect{
[
id: it.id ,
name: it.name
]
}
]
}
]
render seasonJSON as JSON
1 Kommentare:
Hi
This is a quite straightforward and nice to read article. Thanks for sharing your knowledge. It helped me a bit. =)
Greets from Berlin.
Kommentar veröffentlichen