2016-09-28 1 views
2

ich für eine elegante Art und Weise bin auf der Suche eine JSON aus dem folgende Szenario zu erstellen:Scala PlayFramework: zwei Seq der verschiedenen Modell zusammenführen und erstellen JSON schreiben

Angenommen, ich zwei Fallklassen als Modelle habe

case class PersonModel(id: Int, name: String) 
case class CarModel(id: Int, model: CarModel) 

Nach Abfrage meiner Datenbank ich ein Seq [PersonModel] und Seq [CarModel] abrufen. Ich möchte beide Sequenzen in einem einzigen JSON Array der folgenden Struktur schreiben:

[{Person1}, {Car1}, {Person2}, {Person3}, {Car3}] 

So alle Elemente durch ihre ID Sortier- und sie dann in einem einzelnen Array zu schreiben ist, was ich tun möchte. Wie gehen erfahrene Scala/Play Benutzer vor?

Meine Lösung ist ein bisschen ungeschickt, da ich Typinformationen verliere. Zuerst konvertiere ich die Autos zu Personen.

implicit def convert cars2Persons(car: CarModel) = 
    PersonModel(id = car.id, name = car.model) 

Danach muss ich String Kontrollen auf meinem Writes[Person].

+1

bieten Wäre es nicht viel besser sein, Ihre sortierte Liste von 'Persons' zu schreiben, ein' Writes [Person] 'und ebenfalls mit der Verwendung von' Autos und verketten sie dann, wenn Sie sie im gleichen Json-Objekt wollen? Dies hält Ihre Modelle (und die Read/Writes, die damit umgehen können) entkoppelt. Senden Sie dies in einer Antwort zurück, und wenn ja, ist dies eine clientseitige Anforderung? Wenn ja, würde ich die Client-Seite herausfordern. Es ist nicht gut, deine "Autos" in "Personen" umzuwandeln. – Nio

+0

"Autos" in "Personen" umzuwandeln ist definitiv schlecht. Das ist der Hauptgrund für meine Frage, aber ich möchte auch ein einzelnes Array von Elementen. – HknLof

Antwort

1

Dies sieht wie ein klassischer Anwendungsfall für existenzielle Typen aus.

Sie können einen existentiellen Typparameter als T forSome {type T}

import scala.language.existentials 
import play.libs.json._ 

case class Person(id: Int, name: String) 
case class Car(id: Int, model: String) 

implicit val personFormat = Json.format[Person] 
implicit val carFormat = Json.format[Car] 

val listOfCars = List(
    Car(id = 1, model = "Tardis"), 
    Car(id = 2, model = "Tardis"), 
    Car(id = 3, model = "Tardis"), 
    Car(id = 4, model = "Tardis") 
) 

val listOfPersons = List(
    Person(id = 1, name = "The Doctor"), 
    Person(id = 2, name = "The New Doctor"), 
    Person(id = 3, name = "The All New Doctor") 
) 

val list = List.empty[T forSome {type T}] ++ listOfPersons ++ listOfCars 

val sortedList = list.sortBy({ 
    case Person(id, name) => id 
    case Car(id, model) => id 
}) 

val json = Json.toJson(sortedList) 

val jsonString = Json.stringify(json) 
+0

danke. Dies hat sicherlich funktioniert, mein Team und ich entschieden uns, ein drittes Modell zu erstellen und mit einer dritten Eigenschaft zu konvertieren, die beschreibt, ob es ein Auto oder eine Person ist. Jetzt weiß ich ein bisschen mehr über scalas * existentielles * Feature. – HknLof

Verwandte Themen