LoginSignup
3
2

More than 5 years have passed since last update.

Playでクエリストリングをcase class(自分型、任意のオブジェクト)で受け取る

Last updated at Posted at 2016-12-29

QueryStringBindableの話です。
配列で受け取る記事を書く際の調べもの中からの思い付きで。
- Playでクエリストリングを配列(List)や任意の型で受け取る

ソースコード

作ったソースの動作仕様的なもの

次のようなクエリからCellsオブジェクトにバインディングする。

クエリストリング

?cells.colums=4&cells.rows=5

Cellsの定義

Cells.scala
case class Cells(columns: Int, rows: Int)

描画

受け取ったCellsのcolumnsを列、rowsを行として「■」を描画

  • 3×4
    1.PNG

  • 2×5
    2.PNG

ソースコードのポイント抜粋

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の順番は逆のほうがいいなと後で思いました。。。 本質的な内容でないため今回は修正せず。。。

参考にしたもの

Play 2.x の QueryStringBindable, PathBindable について
公式ドキュメント-

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2