私はSlick 3.1.xでPlay 2.4を使用しています。具体的にはSlick-Play plugin v1.1.1です。まず、いくつかの文脈...私は一緒に4つのモデル合流DAOで次の検索/フィルタ方法を、持っている:SlickモナディックジョインからJsonに一連の結果をマッピングする
def search(
departureCity: Option[String],
arrivalCity: Option[String],
departureDate: Option[Date]
) = {
val monadicJoin = for {
sf <- slickScheduledFlights.filter(a =>
departureDate.map(d => a.date === d).getOrElse(slick.lifted.LiteralColumn(true))
)
fl <- slickFlights if sf.flightId === fl.id
al <- slickAirlines if fl.airlineId === al.id
da <- slickAirports.filter(a =>
fl.departureAirportId === a.id &&
departureCity.map(c => a.cityCode === c).getOrElse(slick.lifted.LiteralColumn(true))
)
aa <- slickAirports.filter(a =>
fl.arrivalAirportId === a.id &&
arrivalCity.map(c => a.cityCode === c).getOrElse(slick.lifted.LiteralColumn(true))
)
} yield (fl, sf, al, da, aa)
db.run(monadicJoin.result)
}
これからの出力は、配列を含むベクター、例えば次のとおりです。
Vector(
(
Flight(Some(1),123,216,2013,3,1455,2540,3,905,500,1150),
ScheduledFlight(Some(1),1,2016-04-13,90,10),
Airline(Some(216),BA,BAW,British Airways,United Kingdom),
Airport(Some(2013),LHR,Heathrow,LON,...),
Airport(Some(2540),JFK,John F Kennedy Intl,NYC...)
),
(
etc ...
)
)
私は現在、そうのような、地図上.toJsonを呼び出し、このベクトル(以下results
のparam)を挿入することによって、コントローラにJSONをレンダリングしています:
flightService.search(departureCity, arrivalCity, departureDate).map(results => {
Ok(
Map[String, Any](
"status" -> "OK",
"data" -> results
).toJson
).as("application/json")
})
WORこの種の間ks、それはoutput in an unusual formatを生成する;各結果オブジェクト内の結果(行)の配列。キーは "_1"、 "_2"などのオブジェクト内に入れ子になっています。
質問は次のとおりです。これを再構築するにはどうすればよいですか?
この種のシナリオを具体的にカバーするものは、Slickのドキュメントでは表示されません。したがって、SeqのVectorをリファクタリングするための最良の方法は、各結合の名前を変更したり、特定のフィールドのみを保持したりすることに感謝します。
これは、DAO検索メソッドが返される前に(何とかマッピングすることによって)、または検索メソッドからFuture results Vectorを取得した後にコントローラで実行するのが最適ですか?
あるいは、transformerをおそらく使用して、この種の突然変異を完全に別の場所に抽象化することが望ましいかどうかは疑問です。
おかげですべてを持っています。私はすでにJsonマクロを使っているすべてのクラスに対して 'Writes [T]'を用意しています。これは、結合クエリから返されたVectorだけです。現在、DAOの検索メソッドは、前述のように一連のオブジェクトを含む汎用Vectorを返すだけです。結果のVectorのキャリヤとして機能するために新しいオブジェクトを定義する必要があります。その内部には 'Writes.seq [T]'というresultWrites値を追加しますか?それ以外の場合はどこに行くのですか? –
これはコントローラ上の 'flightService.search'の呼び出しの上に示唆したものを追加することで動作します。私はこれが正しい場所だと確信していない、私は 'val itemWrites:OWrites ...'と 'val resultWrites:Writes ...と推測する'形質を介して混在する可能性があります。それはコントローラーでそれを持つことを正しく感じていませんが、同様に結果シーケンスを保持する擬似モデルオブジェクトを定義することは実際には意味がありません。とにかく、これであなたの指導のおかげで再び、それは大きな助けとなっています。 –
擬似モデルを定義できますが、次に独自の書き込みを実装する必要があります。 'Writes.tupled'は' Tuple'によって実装されたそのような擬似モデルの単なるライターです。あなたの書き込みはシンプルで、より複雑です。私はテストのためだけにコントローラのアクションの外に移動しようとします。この書き込みをコンパニオンオブジェクト内に移動することができます(コントローラーがクラスとして実装されている場合)。 –