ユーザーと投稿の紐付け
前回でユーザー登録できるようになりましたので、今回はユーザーと投稿の紐付けを行っていきます。
流れとしてはこんな感じで作っていきます。
・投稿画面の作成(post.scala.htmlファイルの作成)
・routesの設定
・controllersで投稿ページのpostアクションとデータの送信先としてのaddPostを作成
・ログインユーザーの自身の投稿のみを閲覧できるページ作成
ちなみに現在のpostのentityはこうなっています。
case class Post( @Column("post_id") id: Long, @Column("title") title: String, @Column("content") content: String, @Column("user_id") userId: Int ) extends KeyedEntity[Long] { }
schema設定は前回のentity定義の際に行いましたので、変更点はありません。
val postTable = table[Post]("post")
・投稿画面の作成(post.scala.htmlファイルの作成)
では最初に投稿画面の作成(post.scala.html)をしていきたいと思います。
ユーザーIDはユーザーが直接変更するものではないため、type="hidden"で渡しています。
@(form: play.api.data.Form[db.Post], userData: UserData) @helper.form(action = routes.AdminController.addPost) { //hiddenに対応したhelperはないためHTML形式で <input type="hidden" name="user_id" value="@userData.id" /> @helper.inputText(form("title")) @helper.inputText(form("content")) <input type="submit"/> }
・routesの設定
次にroutesファイルの設定ですが、今回は投稿画面とユーザーが入力したデータの送信先が必要です。なので下記のように記述します。
//投稿画面用
GET /admin/post @controllers.AdminController.post
入力データの送信先
POST /admin/addPost @controllers.AdminController.addPost
・controllersの設定(投稿ページのpostとデータの送信先としてaddPostを作成)
controllersではpostとaddPostの作成を行っていきます。
//postページでは、user_idを参照できるようにユーザー情報を渡します def post = SecuredAction { implicit request => Ok(views.html.post(postForm, request.user)) } //投稿はログインユーザーのみ可能なためSecuredActionつける def addPost = SecuredAction { implicit request => postForm.bindFromRequest.fold( errors => { BadRequest }, //postページで受け取った情報をDBに反映する post => { inTransaction(if(request.user.id == post.userId) AppDB.postTable.insert(post)) Redirect(routes.AdminController.index()) } ) }
これで投稿時にuser_idとpost_idが紐付けられるので、特定のユーザーの投稿のみの表示ができるようになりました。
・ログインユーザーの自身の投稿のみを閲覧できるページ作成
仕上げにログインユーザーが自分の投稿のみ閲覧できるページを作成します。
controllersの設定
def index = SecuredAction { implicit request => transaction { //ページを閲覧しているユーザーのidをwhereで指定 val posts = from(AppDB.postTable)(p => where(p.userId === request.user.id) select (p)).toList Ok(views.html.index(posts, request.user)) } }
ユーザー自身の投稿を閲覧するためのページ
ここはあまり変更点ないため説明は飛ばします。
@(posts: List[db.Post], userData: UserData) <p>@userData.userName</p> ■<a href="@routes.AdminController.post">Post</a> <ul> @for( post <- posts ){ <li>@post.title, @post.content <p> ■<a href="@routes.AdminController.deletePost(post.id)">Delete</a> ■<a href="@routes.AdminController.update(post.id)">Update</a> </p> </li> } </ul>
routesファイルでも変更点はありません。
これでユーザーと投稿の紐付け、特定のユーザーと紐付けられた投稿の表示までできました。
今回作ったものはよくあるwebサービスのマイページのユーザー自身の投稿ページと思ってもらえたらイメージしやすいかと。
次回は一般のユーザーが投稿を閲覧できて、かつコメントできるページを作成していきます。