【Laravel 道場】仕様書から作る実践型課題


 今回、私が挑戦した課題がとても良いものだったので、皆さんにも是非挑戦してもらいたくてこの note を作成しました。この課題は、「動くものをとりあえず作る」のではなく、「自分で考えて実装するという体験」を重視して作られているので、よくあるチュートリアルのような解決までの細かい説明はありません。分からないことがあれば、Laravelのリーダブルを読んだり、PHPマニュアル、Google先生の力を借りながら、自分で一から作り上げていきます。実務体験をしてみたい方、自分の力を試してみたい方、実力アップしたい!方におすすめします。

 参考に、この課題に取り組む前の私のスキルレベルは、HTML、CSS(模写できる程度)、PHP(超基礎レベル)、Ruby on Rails チュートリアル1周したくらいです。GETやPOSTについて事前に理解しているとかなり有利になると思いますので、自分のスキルに合わせて予習してみてください。


【今回の仕様書】

 それでは、今回の課題の仕様書をダウンロードしてみましょう。

 この仕様書にそって、まずはTwitterでも紹介した以下のようなアンケートフォームを作っていきます。

 これがフロントページとなり、ここでアンケートを募集してデータベースに登録、保存されるようにします。また後半では、ログインをしたらアンケートを管理できる管理サイトページも作成します。

 それでは、順を追って課題を進めていきましょう!gitが使える方は、課題ごとにpushしておくと良いと思います。完成したら、GitHubなどで公開するのも実績が残っていいと思います。


【課題1 HTMLフォーム】

1. Laravelをインストールし、ローカル環境を整える。

2. /resources/viewフォルダにindex.blade.phpでhtmlを作る。

3. index.blade.phpに仕様書1ページ目のフォームを作成する。

パスが通らないというトラブルを上記のサイトで解決しました。

echo $PATH

で、通っているパスが確認できます。

 LaravelにはBootstrapが初めから入っているので、簡単に整ったフォームが作れて便利ですね。初心者の方は、なるべくLaravel Formファザード{{ Form::label('name', 'Your Name') }}などは使わないで、HTMLの記法で進めていった方が理解が深まると思います。


ーCheck!ー

・フォームの「男性」「女性」「送信を許可します」などの文言をクリックした時、チェックがついたり外れたりしますか?

・デフォルトでチェックが入るものはチェックされていますか?


【課題2 MySQL接続】

1. .envを追加して、mysqlと接続する。

Sequel Pro は使わなくて大丈夫です。

2. マイグレーションファイルを作成して DB にテーブルを入れる。(テーブル定義は仕様書の3ページ目に書いてあります。)
  -answers
  -ages
  の2つのテーブルを作成します。

 今回は一人で開発しているので、マイグレーションは間違ってしまってもロールバックして何度でもやり直しができます。ロールバックの項目をよく読みましょう。削除したいマイグレートファイルは、ロールバックしてから削除しましょう。

MySQL8.0 でエラーが出たので、これで解決しました。


ーCheck!ー

・DBの設定はconfig/database.phpではなく.envに書いてありますか?

・answersテーブルのカラム'id'は、数が増えた時に自動で増える属性になっていますか?


【課題3 シーディング】

 agesのシーダクラスを作成して、初期値として以下の年代のデータを入れられるようにする。

id|age|sort
1|10代以下|1
2|20代|2
3|30代|3
4|40代|4
5|50代|5
6|60代以上|6


ーCheck!ー

データベースに値が入ったか確認してみましょう。


【課題4 コントローラ】

1. FrontControllerを作成する。

2. FrontControllerにindexのビュー用のメソッドを追加して、ルートURL(http://localhost:8000 )でアクセスしたときにindex部分が表示されるようにする。

・ルートURLにアクセスした時にアンケートの入力フォームが表示されるようにしてください。

・年代のセレクトボックスはagesのデータを使ってください。

( ages sort 順に並ぶようにデータベースから引っ張るコードをコントローラに書き、ビューでPHPのforeach文を使ってうまく表示しましょう。)

画像1

・modelの作成は必要に応じて作っても作らなくてもどちらでも構いません。

ーCheck!ー

・セレクトボックスのデフォルトは「選択してください」になっていますか?(foreach文の外で書き、selectedを入れましょう。)


【課題5 リクエスト・Bladeテンプレート】 

ここは自分でコードを考えていく踏ん張りどころ。頑張りましょう!

1. FrontControllerにconfirmメソッドを追加する。http://localhost:8000/indexで確認ボタンを押すと、http://localhost:8000/confirmにPOSTして、登録内容を表示するようにする。

・$request->input('fullname'); などを使ってうまくデータを引っ張りましょう。引っ張ってきたデータには何が入っているのかをよく考え、必要に応じてPHPの配列を作成し、うまくビューに表示できるように頑張ってください。

(ヒント)例えばgenderデータには数字が入っていますから、そのままでは数字がビューに表示されてしまいますね。1には「男性」、2には「女性」が入る配列をコントローラ側で別で作って、genderデータとうまく組み合わせてみましょう。

・{{ var_dump($変数名) }}をビューに置くと、何がその変数に入っているかを表示してくれるので、開発するのにとても便利です。

画像2

2. indexとconfirmで共通部分はテンプレート化する。

・テンプレートは
resources/views/front/layouts/app.blade.php として置いてください。

・index、confirmはそれぞれ resources/views/front/index.blade.php、resources/views/front/confirm.blade.php としてください。


ーCheck!ー

・feedbackは入力画面で改行させた場合、確認画面でも改行して表示されますか?

課題5をクリアできると、かなりレベルアップが実感できるので頑張りましょう!


【課題6 バリデーション】

 バリデーション(入力チェック)を設定して、入力に間違いがある時はエラーで入力画面へ戻す。

・feedbackの文字数は10000くらいに設定しておきましょう。

画像3

 私はオリジナルでバリデーション時の文言をシンプルに設定してみました。


【課題7 データの保存】

1. 再入力ボタンを押すと、入力した文字が保持されるように入力画面に戻るようにする。

・old()を使います。チェックボックスや、セレクトボックスはPHPで条件分岐をする必要があります。

(例)もし選択された値が1だったら、チェックする 
(例)もし選択された値がvalueに入っている値と同じだったら、セレクトする

2. confirmで[送信]ボタンをおすとデータが登録されるようにする。

 登録できたらindexに戻してください。indexに戻ったら [アンケートを送信しました] というメッセージをフォームの上部に出してください。

画像4

 仕様書では違うページが用意されていますが、突然の仕様変更も業務のうち!(笑)フォームの上部にメッセージが表示されれば良いです。

・詳しく説明はしていませんが、コントローラに新しいメソッド(storeなど)を作ってリクエストから渡された値をsaveできるように作ってみましょう。

ーCheck!ー

・送信を許可しないとした時、再入力時にチェックは外れていますか?

(ヒント)oldがなく、なおかつチェック値が1の場合チェックする としましょう。

・データを保存する際に、バリデーションはされていますか?

(ヒント)たとえば確認画面の

<input type="hidden" name="fullname" value="{{ $fullname }}">

を、

<input type="hidden" name="fullname" value="">

と書き換えてみて、送信ボタンを押すととどうなりますか?

ここまでで、バリデーションがついた立派なアンケートフォームが完成しました。ですが、あくまで課題用です。実際に使われているものはもう少しセキュリティが高いので、そのまま使うことはしないでください。


 では、これから以下のような検索機能をつけたアンケート管理サイトを作成します。


【課題8 ログイン認証】

/systemでアクセスすると、ログイン画面を表示するようにする。

画像5

・いらない機能もありますが、とりあえずはデフォルトの認証機能を使ってください。

 Auth機能はとても便利なのですが、初心者には中身が分からないと理解しづらいです。特にAuth::routes();の中身は知っておいた方がいいと思うので、ルートを1行ずつ書いてみると理解が深まると思います。下のサイトを参考にルートを設定してみましょう。

ログイン画面などはデフォルトでは英語なので、私は日本語に直してみました。


【課題9 一覧表示】

 AnswerControllerを作成して、indexメソッドにanswersレコードの一覧を表示する。アンケート一覧のURLは/system/answer/indexとする。また、ログインするとこのページを表示するようにしてください。

画像6

・一覧に表示する項目は id|氏名|性別|年代|内容 です。
MAX10行表示させて、それ以上はページングをつけるようにしてください。

・feedbackの項目は15文字でカットして、末尾に...をつけるようにしてください。
・全件数と今のページで表示されている件数を表示してください。
・「詳細」ボタンは今は形だけ作っておきます。

ーCheck!ー

・/system/answer/indexページはログインユーザのみ閲覧可能となっていますか?(直接URLにアクセスしてみたときに、ログイン機能は機能していますか?)


【課題10 検索】

 今回の課題の中でもっとも難関といえます。はじめにも載せましたが、GETとPOSTについて理解がないと厳しいので、必ずよく読んでから取り組みましょう。

検索するには、GET・POSTどちらを使うか分かったら先に進みましょう。

1. 一覧画面に検索フォームを作成し、検索機能をつける。

画像7

検索項目は、
氏名 (LIKE検索)
年代
性別
登録日(created_at、始まり日と終わり日も設定して、その期間内にcreated_atが当てはまるものを検索させてください。)
メール送信可否
キーワード(feedbackとemailをLIKE検索させてください。)

です。検索フォームの下に [リセット] [検索] というボタンをつけて、[リセット] を押すと入力フォームを空にして、[検索] を押すと検索されるようにしてください。

(ヒント)
「もし、$name(検索画面で氏名欄に入力された文字が入る変数)が空ではなかったら $queryには Answerテーブルの fullnameカラムから、Like検索で、$nameを含む文字で絞って表示させる」・・・
「もし、$gender(検索画面で選択されたものが入る変数)が空ではなかったら ・・・」を繰り返し、一覧ページを表示させるイメージです。

2. リセットボタンを簡単なJavaScriptを使って、クリックしたら /system/answers/index にリダイレクトされるようにする。

3. 一件も該当するアンケートがない場合は、お知らせを出す。

画像8


ーCheck!ー

・アンケートを数十件ほど登録し、検索機能を一通りチェックしてみましょう。(一件ずつアンケートを登録していくのは大変なので、「faker」を使ってみましょう。)

性別と名前がランダムに生成されるので、「女性」で検索すると

画像9

オネエ様が生成される事態となり、Factory内で手直ししてあげました。fakerには女性名と男性名があるので、if文で分岐させてあげると、

画像10

いい感じになります。

・検索後のページネーションや、件数のカウントは正常に表示されていますか?

検索機能が作れるようになると自信がつくので、ぜひチャレンジしてみてくださいね!



【課題11 詳細画面】

 アンケート管理画面に詳細画面を作成する。AnswerController の show で /system/answers/{answer.id} にアクセスすると表示できるようにしてください。

Answerモデルを作成してAnswersテーブルと紐づけておけば、モデル結合ルートが使用できるので簡単ですね。

画像11

一覧に戻るボタンを押すと、検索した直前のページに戻るようにしてあげると親切ですね。削除ボタンの中身は次の課題で作ります。


ーCheck!ー

・feedbackに改行があった場合、反映されていますか?


【課題12 削除】

 詳細画面に削除機能をつけてください。削除が行われたら、「削除しました」とお知らせが出るようにしましょう。

画像12


ーCheck!ー

・削除する前に、「削除してもよろしいですか?」と確認メッセージは出ますか?


【課題13 選択削除】

 やや発展課題です。一覧画面に複数選択したあとに [選択したアンケートを削除] ボタンをおすと、選択したレコードを削除するプログラムをつけてください。

画像13

全選択などは、JavaScriptを使いましょう。実装方法は自分で調べてみてください。


【あとがき】

 以上で、今回の課題は終了です。後半はヒント少なめですが、そこまで出来たらきっとできるはずです!この課題を通じて、Laravelって楽しいなぁ〜、プログラミングもっとやりたい!と思ってもらえれば嬉しく思います。私の場合、終えるのにだいたい1ヶ月ほどかかりました。難しくて進まず、3日そのままだったりもしました。ですが、諦めずに全てやり切るとかなりの達成感があると思います。

 Twitter上では、こんな声も。

 ぜひ、皆さんにも頑張ってみて欲しいと思います。それでは良いプログラミングタイムを♪


この記事が気に入ったらサポートをしてみませんか?