質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • Scala

    184questions

    ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

  • Play Framework

    31questions

    Play Frameworkは、現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

Play Framework(Scala版)のvalidate内でのSlickの利用方法について

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 1,092

ts.tubasa

score 111

Play Framework 2.4のJava版を、Scala版(Play 2.5.x)+Slick3へ置き換えを始めようと考えております。
Scalaの知識は、コップ本を読んで少しサンプルを書いた程度なので、これを気にしっかりと覚えていきたいと思っております。

Java版とScala版での違いでわからないことがあり、質問させて頂きます。

FormのValidateの使い方でvalidate内でDBへアクセスする方法を教えてほしいのですが、Javaでは、Form用のオブジェクトを用意してその中で、DBへアクセスし存在チェックなどを行っておりました。

public List<ValidationError> validate() {

        List<ValidationError> errors = new ArrayList();

        //ここで存在チェック

        return 0 < errors.size() ? errors : null;
    }

Scalaの場合、コントローラーに、validateを記述し、そこで、DBへアクセスを行って存在チェックをしようとしております。

class BookController @Inject()(book: bookDao)(implicit context: ExecutionContext) extends Controller {

  def validate(name: String, category: String) = {

    logger.debug(bookDataId)

    val f = book.isPrice(name, category)
    f.isCompleted match {
      case true =>
        Some(BookData(name, category))
      case _ =>
        Some(null)
    }
  }

  val userForm = Form(
    mapping(
      "name" -> text,
      "category" -> text
    )(BookData.apply)(BookData.unapply) verifying("エラー", fields => fields match {
      case bookData => validate(bookData.name, bookData.category).isDefined
    })
  )
}
class BookDao @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)
  extends HasDatabaseConfigProvider[JdbcProfile] {

  import driver.api._

  val booktable = TableQuery[BookTable]

  def all(): Future[Seq[Book]] = db.run(booktable.result)

  def isPrice(name: String, category: String): Future[Option[BookTable]] =
    db.run(
      booktable.filter(
        n =>
          (n.name === name) && (n.category === category)
      ).result.headOption)
}

DBへの問合せが行われていることは、ログを出力して確認しております。
Slick3が、非同期でのDBへの問合せとなっており、validate内で実行した際に、
validateの後に、SQLが実行されてしまっております。

そもそも、こういった使い方でよいのか?
検討もつかず、わからなくなり質問させていただきました。

上記のソースを踏まえ、一般的な、Play Scala のvalidateの使い方について、ご教授いただけないでしょうか?

よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

これは私も、どうするのが一般的かわかっていませんが、とりあえず私が採用した解決法を書きます。

Slick3が、非同期でのDBへの問合せとなっており

まず1つは、ここに問題があるので、validate の内容を下記のように書き換えると良いと思います

import scala.concurrent.Await
import scala.concurrent.duration.Duration
import play.api.libs.concurrent.Execution.Implicits._

/// ...
def validate(name: String, category: String): Option[BookData] = {
  val fut = for(isPrice <- book.isPrice(name, category)) yield {
    if(isPrice) Some(BookData(name, category)) else None
  }
  Await.result(fut, Duration.Inf)
}

ScalaのFutureについて調べていただければ、↑が何をやっているのかはすぐわかると思います

それと、Option型についてですが、 Some(null) は そのまま Some(null) が返ります。
このような場合では、 Option(null) にするか、 None を利用します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ご回答ありがとうございます。

「Await.result」がポイントですね。

ありがとうございました。

Scala素人には、Slick3よりも、EBeanやScalikeJDBCの方が使いやすく感じました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Scala

    184questions

    ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

  • Play Framework

    31questions

    Play Frameworkは、現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。