焼け石に肉

新米プログラマの学習記録日記です。Scalaに興味があるので、ScalaとPlay Frameworkの勉強メモを残していこうと思います。

【Scala】Scala&Play Frameworkで掲示板を作ってみる Part2【Play Framework】

前回の続きです。

今回はルーティングとコントローラーについて、書いていきます。

 

routes

GET         /                           controllers.Default.redirect(to = "/messages")
# メッセージ一覧画面の表示
GET         /messages                   controllers.MessageController.index
# メッセージ詳細画面の表示
GET         /messages/:id/get           controllers.MessageController.showDetail(id: Long)
# メッセージ作成画面の表示
GET         /messages/create            controllers.MessageController.showCreate
# メッセージ編集画面の表示
GET         /messages/:id/update        controllers.MessageController.showUpdate(id: Long)

# メッセージの作成
POST        /messages/create            controllers.MessageController.create
# メッセージの更新
POST        /messages/update            controllers.MessageController.update
# メッセージの削除
POST        /messages/:id/delete        controllers.MessageController.delete(id: Long)

GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)

ルーティングについては、上記の通りです。
トップページは、
controllers.Default.redirect(to = "/messages")
によって、リダイレクト処理を行っています。
その他は、DBへの読み書きの処理についてのルーティングです。

MessageController

package controllers

import java.time.ZonedDateTime
import javax.inject.{ Inject, Singleton }

import forms.MessageForm
import models.Message
import play.api.i18n.{ I18nSupport, Messages, MessagesApi }
import play.api.mvc.{ Action, AnyContent, Controller }
import scalikejdbc.AutoSession

@Singleton
class MessageController @Inject()(val messagesApi: MessagesApi)
    extends Controller
    with I18nSupport
    with MessageControllerSupport {

  def index: Action[AnyContent] = Action { implicit request =>
    val result = Message.findAll()
    Ok(views.html.index(result))
  }

  def showDetail(messageId: Long): Action[AnyContent] = Action { implicit request =>
    val message = Message.findById(messageId).get
    Ok(views.html.show(message))
  }

  def showCreate: Action[AnyContent] = Action { implicit request =>
    Ok(views.html.create(form))
  }

  def showUpdate(messageId: Long): Action[AnyContent] = Action { implicit request =>
    val result     = Message.findById(messageId).get
    val filledForm = form.fill(MessageForm(result.id, result.body, result.title))
    Ok(views.html.edit(filledForm))
  }

  def create: Action[AnyContent] = Action { implicit request =>
    form
      .bindFromRequest()
      .fold(
        formWithErrors => BadRequest(views.html.create(formWithErrors)), { model =>
          implicit val session = AutoSession
          val now              = ZonedDateTime.now()
          val message          = Message(None, model.body, model.title, now, now)
          val result           = Message.create(message)
          if (result > 0) {
            Redirect(routes.MessageController.index())
          } else {
            InternalServerError(Messages("CreateMessageError"))
          }
        }
      )
  }

  def update: Action[AnyContent] = Action { implicit request =>
    form
      .bindFromRequest()
      .fold(
        formWithErrors => BadRequest(views.html.edit(formWithErrors)), { model =>
          implicit val session = AutoSession
          val result = Message
            .updateById(model.id.get)
            .withAttributes(
              'body     -> model.body,
              'title    -> model.title,
              'updateAt -> ZonedDateTime.now()
            )
          if (result > 0)
            Redirect(routes.MessageController.index())
          else
            InternalServerError(Messages("UpdateMessageError"))
        }
      )
  }

  def delete(messageId: Long): Action[AnyContent] = Action {
    implicit val session = AutoSession
    val result           = Message.deleteById(messageId)
    if (result > 0) {
      Redirect(routes.MessageController.index())
    } else {
      InternalServerError(Messages("DeleteMessageError"))
    }
  }

}

このコントローラーの中で、下記をミックスインしています。

MessageControllerSupport

package controllers

import forms.MessageForm
import play.api.data.Forms._
import play.api.data._
import play.api.mvc.Controller

trait MessageControllerSupport { this: Controller =>

  protected val form = Form(
    mapping(
      "id"    -> optional(longNumber),
      "body"  -> nonEmptyText,
      "title" -> nonEmptyText
    )(MessageForm.apply)(MessageForm.unapply)
  )

}

上記によって、フォームのマッピング処理を独立させています。


次回はモデルについて書いていきたいです。