QueryStringBindableの話です。
配列で受け取る記事を書く際の調べもの中からの思い付きで。
ソースコード
作ったソースの動作仕様的なもの
次のようなクエリからCellsオブジェクトにバインディングする。
クエリストリング
?cells.colums=4&cells.rows=5
Cellsの定義
Cells.scala
case class Cells(columns: Int, rows: Int)
描画
受け取ったCellsのcolumnsを列、rowsを行として「■」を描画
ソースコードのポイント抜粋
QueryStringBindableの拡張部分
Cells.scala
object Cells {
implicit def queryStringBinder(implicit intBinder: QueryStringBindable[Int]) = new QueryStringBindable[Cells] {
val columnsKey = "columns"
val rowsKey = "rows"
override def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, Cells]] = {
for {
columns <- intBinder.bind(s"$key.$columnsKey", params)
rows <- intBinder.bind(s"$key.$rowsKey", params)
} yield {
(columns, rows) match {
case (Right(c), Right(r)) => Right(Cells(c, r))
case _ => Left(s"cell's columns and rows must be Integer.")
}
}
}
override def unbind(key: String, cells: Cells): String = s"${intBinder.unbind(s"$key.$columnsKey", cells.columns)}&${intBinder.unbind(s"$key.$rowsKey", cells.rows)}"
}
}
ポイント
- Intのbind,unbindには既存の実装を利用
- エラー処理は簡単のためまとめているが、細やかな制御も可能
- Leftで返したものはどこへいく?(今後調査します)
routes
GET / controllers.TestController.index(cells: controllers.request.query.Cells)
- CellsのコンパニオンオブジェクトにQueryStringBindableの拡張を定義しておけば、それだけでroutesに記述することができる
感想・備考等
- 今回の仕様だとオブジェクトにする必要ないじゃんというツッコミはなしで。。。
- 「行列」なのでCellsのcolumnsとrowsの順番は逆のほうがいいなと後で思いました。。。
本質的な内容でないため今回は修正せず。。。