Skip to content

Instantly share code, notes, and snippets.

@nisshiee
Created July 16, 2012 11:25
Show Gist options
  • Save nisshiee/3122213 to your computer and use it in GitHub Desktop.
Save nisshiee/3122213 to your computer and use it in GitHub Desktop.
PlayでurlFormEncodedなデータを受け取る
object PersonController extends Controller with ControllerHelper {
def create = Action(parse.urlFormEncoded) { implicit req =>
val personOpt: Option[Person] = for {
name <- paramOpt[String]("name")
age <- paramOpt[Int]("age")
person <- Person.create(name, age)
} yield person
// あとはResultを作る
}
}
import scalaz._, Scalaz._
object PersonController extends Controller {
def create = Action(parse.urlFormEncoded) { implicit req =>
val personOpt: Option[Person] = for {
name <- req.body.get("name") map {
case Seq(s) => s.some
case _ => none
}
age <- req.body.get("age") map {
case Seq(s) => s.parseInt.toOption
case _ => none
}
person <- Person.create(name, age)
} yield person
// あとはResultを作る
}
}
def param(req: Request[Map[String, Seq[String]]], key: String): Option[String] =
req.body.get(key) map {
case Seq(s) => s.some
case _ => none
}
import scalaz._, Scalaz._
trait ControllerHelper {
// Seq[String]から型Tのデータを抽出する型クラス
trait Extractor[T] {
def extract(data: Seq[String]): Option[T]
}
// Extractorを簡単に生成できるようにする
def extractor[T](f: Seq[String] => Option[T]): Extractor[T] = new Extractor[T] {
def extract(data: Seq[String]) = f(data)
}
// 他の型のExtractorとの連携も簡単にできるように
def extractorBy[T, B](f: B => Option[T])(implicit extB: Extractor[B]): Extractor[T] =
extractor[T] { extB.extract(_) >>= f }
// こいつがControllerで実際に呼び出す関数
def paramOpt[T](key: String)(implicit req: Request[Map[String, Seq[String]]], ext: Extractor[T]): Option[T] =
req.body.get(key) >>= ext.extract
// OptionじゃなくてValidationで受け取りたい時用
def paramVld[E, T](key: String)(err: => E)(implicit req: Request[Map[String, Seq[String]]], ext: Extractor[T]): Validation[E, T] =
paramOpt[T](key).toSuccess(err)
// よく使う型のExtractorは予め作っておきやしょう
implicit lazy val StringExtractor = extractor {
case Seq(s) => s.some
case _ => none
}
// Extractor[String]とString => Option[Int]を組み合わせてExtractor[Int]を作る
implicit lazy val IntExtractor = extractorBy[Int, String] { _.parseInt.toOption }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment