Laravelでスレッド型BBSをつくってみた① - ソース公開中

# はじめに

人のコードを読むのは非常に勉強になります。しかし、まだ勉強中という自覚のある人にはむしろ敷居が高いのかもしれません。敷居が高くなってしまう理由として、以下の理由を考えてみました（憶測）

1. 勉強中の身だと学習の効率ばかり気にして、具体的にどのコード読めば効率的な学習に繋がるのかわからず、結局手が付けられない
2. 難し過ぎて心が折れる

1については、本当は実際に利用するライブラリあたりから手をつけるのがいいんですが、そうすると2の問題がでてきたりした経験ありません？これらの問題を解決するために、「とりあえずこれ読んでみたら？」的なコードを書いてしまえばいいんじゃないかと思い立ったのが本稿のきっかけでございます。

ついでに開発や改修の様子なんかも少し伝わるといいかと思うので、とりあえず認証機能すらなく、管理すらできない極めて簡素なヘボ掲示板からはじめたいと思います。これに少しずつ機能追加や改修を加えることで、段階的にコードリーディングを進めていけるようになるんじゃないかな？という狙いです。

開発の方針としてできるだけLaravelのスタンダードに沿う形にしたいと思っていますが、もしかしたら自分の知らない間にスタンダードから逸脱している可能性もあるのでその時は優しくコメントで指摘してください。

# 軽く仕様策定 & 設計

## 超簡単仕様

+ 基本匿名（任意での記名は可能）
+ スレッドは誰でも作れる。
+ スレッドへの投稿も誰でもできる。
+ スレッドと投稿は誰も削除/編集できない

## テーブル

面倒臭いので雰囲気だけお伝えします（屑）

threads : entries = 1 : N

外部キー制約とかそういうのはなしでいいよね？（震）

### threads（スレッド）

| カラム名（論理名）       |       物理名 |型|その他|
|:-----------------|:------------------|:--|:--|
| ID|id|integer|auto increment|
| 投稿者|name|varchar(255)|nullable|
| タイトル|title|varchar(255)|not null|
| 内容|content|text|not null|
| 削除日|deleted_at|timestamp|nullable|
| 作成日|created_at|timestamp|not null|
| 更新日|updated_at|timestamp|not null|

### entries（投稿）

| カラム名（論理名）       |       物理名 |型|その他|
|:-----------------|:------------------|:--|:--|
| ID|id|integer|auto increment|
| スレッドID|thread_id|integer|not null|
| 投稿者|name|varchar(255)|nullable|
| 投稿|content|varchar(255)|not null|
| 削除日|deleted_at|timestamp|nullable|
| 作成日|created_at|timestamp|not null|
| 更新日|updated_at|timestamp|not null|



## 画面

+ スレッド一覧画面（スレッド投稿フォーム含む）
+ スレッド詳細画面（投稿フォーム含む）

# 開発

https://github.com/new-japan-orders/bbs

## まずは画面作成

以下の作業はphase-1-1ブランチで行いました。

とりあえず画面を作成してRouteで直接指定して表示できるところまで作業します。
作成する画面はスレッド一覧画面とスレッド詳細画面、それに共通部分をまとめておくためのレイアウトです。

+ resources/views/layouts/app.blade.php
+ resources/views/threads/index.blade.php
+ resources/views/threads/show.blade.php

CSSはresouces/sass/app.scssに追記していきます。また、今回はVueを利用する予定がないため、resources/js/app.jsの不要箇所もコメントアウトしてあります。

作業完了後、phase-1ブランチにマージしました。

## モデルとコントローラーを作成

以下の作業はphase-1ブランチから派生したphase-1-2ブランチで行いました。

### 作成するモデルは2つ

+ Threadモデル
+ Entryモデル

### 作成するコントローラーは1つ

+ ThreadsController

### 作成するmigrationファイルは2つ

+ YYYY_MM_DD_HHiiss_create_threads_table
+ YYYY_MM_DD_HHiiss_create_entries_table

### 細く

先ほど作成したRouteを書き直してあります。
とりあえずここではスレッド一覧画面が表示されるところまでで完了とします。スレッド詳細画面はテーブルにレコードがないと表示できないのであとで確認したいと思います。

作業完了後、phase-1ブランチにマージしました。

## 完成させるぞ！

ガワはできあがったのであとは中身を作っていきます。
以下の作業はphase-1ブランチから派生したphase-1-3ブランチで行いました。

### モデルのリレーション

ThreadモデルとEntryモデルに1対多の関係を定義します。

1. Threadにentriesメソッドを追加
2. Entryにthreadメソッドを追加

### テストデータを作成

後々のことを考えてthreadsとentriesにデータを挿入するseederをつくっておきます。Fakerを日本語化しておきたい場合はconfig/app.phpの'faker_locale'を'ja_JP'にしておく必要があります。

1. ThreadFactoryとEntryFactoryを作成
2. ThreadSeederを作成
3. php artisan db:seed --class ThreadSeeder

[参考][LaravelのFakerとSeedingでダミーデータを自動生成しデータベースへ投入する](https://www.ritolab.com/entry/28)

### スレッド一覧表示

ThreadsController@indexにデータ取得処理を記述し、threads.indexビューにて動的に表示するように修正します。ついでにpagerの表示を一部修正しています。

1. ThreadsController@indexにデータ取得処理を記述
2. resources/views/threads/index.blade.phpを修正
3. php artisan vendor:publish --tag=laravel-pagination
4. resources/views/vendor/pagination/bootstrap-4.blade.phpを修正

[参考][ページネーションのカスタマイズ](https://readouble.com/laravel/5.7/ja/pagination.html#customizing-the-pagination-view)

### スレッド詳細表示

1. ThreadsController@showにViewを返す処理記述。
2. resources/views/threads/show.blade.phpを修正

### スレッド作成

Formヘルパーを使いたいのでlaravelcollective/htmlをインストールします。form要素やinput要素をFormヘルパーで書き直したらView側は終了です。

作成処理はThreadsController@storeに記述します。このタイミングでThreadRequestクラスを作成し、ValidationはThreadRequestで行うようにします。

1. composer require laravelcollective/html
2. form要素やinput要素をFormヘルパーで書き直し
3. ThreadRequestクラス作成
4. Validationエラーメッセージの日本語化（composerライブラリで簡単にやります。詳しくは下記の参考サイトをご覧ください。）
5. ThreadsController@store実装

[参考][コメント日本語変換](https://github.com/laravel-ja/comja5)

### 投稿

スレッド作成とほぼ同じです。form要素やinput要素をFormヘルパーで書き直し、ThreadsController@storeEntryを作成します。このタイミングでEntryRequestクラスを作成し、ValidationはEntryRequestで行うようにします。

1. form要素やinput要素をFormヘルパーで書き直し
2. EntryRequestクラス作成
3. ThreadsController@storeEntry実装

### 微調整

+ 投稿フォームが一番下だとわかりづらく感じたので一番上に変更

作業完了後、phase-1ブランチにマージしました。

# とりあえず完了

これでとてもミニマムなスレッド掲示板が完成しました。今後このスレッド掲示板に色々な修正や機能追加を加えていく様子をQiitaでまとめていけたらいいなぁと思っております。

作業の各工程を各ブランチに残してありますので、branch切り替えながらどんな作業しているのか確認したりしつつコードを読んでみてください。

## 予定

+ 認証機能追加
+ MultiAuth
+ EntriesControllerの追加と管理機能の追加