- 投稿日:2021-04-05T23:26:40+09:00
【Laravel】ちゃんとフォームリクエストでバリデーションしてね
*この記事は初心者エンジニア(実務経験あり)が書いている記事です。 こんにちは @erika_chan(qiita) です。 今年度は、たくさんアウトプット出そうと思ってqiitaを始めてみました!! つよつよな人が周りにそんないなくて試行錯誤でやってます 結論 バリデーションしてないWebサービスは危ない! 今はCMSを主に開発していますがもちろんテストはしてないしバリデーションすらしてないっていう悲しい現状だったので、自分が担当するところから積極的に書いていこうということでチョロチョロっと学んでみました! バリデーションのすすめ まずバリデーションはアプリケーションのフォームからデータベースに入れる処理の際に入力され送られてきたデータをチェックして、そのデータが本当にデータベースに入れていいのか判断することです! これがないと本来メールアドレスが入って欲しいカラムに"間抜けなアプリ"のような文字列が簡単に入ってしまうためやるべき処理なのです! ではlaravelではどうやってやるの!という話ですね。 validateメソッドを使う! validateメソッドは連想配列にしたルールを引数に入れるだけで簡単にバリデーションしてくれます。 ArticleController.php /** * 新記事データの保存 * * @param Request $request * @return Response */ public function store(Request $request) { $validatedData = $request->validate([ 'title' => 'required|unique:posts|max:255', 'body' => 'required', ]); } 今回の場合は$requestで受け取ったデータのtitle, bodyが空じゃないかつtitleが255文字以下でデータベースにそのtitleが存在しないことが確認できたらそのまま通ってくれるのです! unique:posts これだけで既存のデータまでも見れるという超便利で優しいlaravelって最高ですね。 フォームリクエストバリデーションを使う これが今回のタイトルにもあるイチオシのばばばバリデーションです! このやり方だとファイルで分かれているので使い回しもできるしコントローラが簡潔に済むのでおすすめです まず以下のコマンドを叩きます。 php artisan make:request StoreArticlePost このコマンドを叩くとHttp/Requestディレクトリ配下にStoreArticlePost.phpというファイルが完成します! それがこちら↓ Http/Request/StoreArticlePost.php /** * ユーザーがこのリクエストの権限を持っているかを判断する * * @return bool */ public function authorize() *1 { // 認証系が必要な場合はfalseにしましょう return true; } /** * リクエストに適用するバリデーションルールを取得 * * @return array */ public function rules() *2 { return [ // titleが存在する、データベースにそのtitleが存在しない、255文字以下 'title' => 'required|unique:posts|max:255', // bodyが存在する 'body' => 'required', ]; } ArticleController.php /** * 新記事データの保存 * * @param StoreArticlePost $request * @return Response */ public function store(StoreArticlePost $request) { // validateメソッドを書かなくても↑だけでok return $response; } ここでは*1に認証についてのロジックがかけます。ただ他のところに書いていたり、そもそも認証する部分ではない場合が多かったりするので基本trueにしておきます。例えば特定のuserしか入力できないデータなのであればパスワードチェックするロジックなどをかけたりします。もしその認証に通っていない場合(falseを返す)は自動的に403を返してくれます! *2では上のvalidationメソッドと同じく既存のルールを用いて各リクエストの中身をチェックして問題なかったら通り、ダメだったら何がダメだったのかを教えてくれるのです。 といった感じでバリデーションがなくても動くアプリケーションはできるんです。 けどやっぱり安全かつどんなデータを入れる場所なのかをバリデーションでわかっちゃうって結構初心者にも優しいと思うんですよね。 web系エンジニアに転職する方はぜひ使ってみてください!
- 投稿日:2021-04-05T23:16:13+09:00
ゴルフスクールの予約システムを作ってみよう!
ポートフォリオとして制作したゴルフスクールの予約システムの制作過程をまとめました。 尚、ポートフォリオとGitHubは下記でございます。 ポートフォリオ「ゴルフスクールの予約システム」URL https://www.golfchamp-reservation.com/login GitHub https://github.com/takayuki007/golfChamp-reservation 1、要件概要 導入 PHPのフレームワークであるLaravelを使ってゴルフレッスンの予約サイトを作ってみます。以前、作ったゴルフレッスンのサイトの予約システムです。 ゴルフレッスンサイトURL: https://takayuki007.github.io/golfChamp/index.html 参考にしたサイトは下記です。 ZERO FUSION https://www.zero-fusion.com/ 2、サービス概要 自分の希望日時と場所でゴルフの個人レッスンを受けるための予約が取れる。 要件定義(10分) ユーザー名、メールアドレスで登録できる。 ユーザー名とパスワードでログインすることができる。 レッスン日とコーチとレッスン場所を明確に。 マイページでレッスンの確認。 PCとスマホに対応。 ページ構成(5分) 新規登録ページ ログインページ マイページ 予約ページ 完了ページ 画面設計&デザイン作成 新規登録ページ(PC25分)(SP10分) ログインページ(PC5分)(SP5分) マイページ(PC10分)(SP5分) 予約ページ(PC10分)(SP5分) 予約確認ページ(PC10分)(SP15分) 完了ページ(PC5分)(SP5分) DB設計(20分) users id id name varchar email varchar password vaerchar email_verified_at timestamp remember_token varchar created_at timestamp updated_at timestamp deleted_at timestamp locations id int name varchar address varchar url text created_at timestamp updated_at timestamp deleted_at timestamp times id int time varchar created_at timestamp updated_at timestamp deleted_at timestamp coaches id int name varchar created_at timestamp updated_at timestamp deleted_at timestamp reservation id int date varchar user_id int location_id int coach_id created_at timestamp updated_at timestamp deleted_at timestamp クラス設計(15分) FLOCSSを採用 全体 app Foundation部分 _reset、_variables Layout部分 l-wrapper、l-site-width、l-margin、l-main、l-header Object部分 Component部分 c-btn-second、c-alert-success、c-btn-area、c-btn、c-form-check-area、c-form-check-label、c-form-group、c-form、c-from-check-input、c-heading、c-input-area、c-input、c-invalid-feedback、c-is-invalid、c-li、c-link、c-logo-link、c-logo、c-reservation-group、c-reservation-li、c-reservation-ul、c-reservation、c-text、c-title、c-ul、c-wrapper Project p-text-center Utility u-space-area、u-margin-top、u-login-link、u-color-red 環境構築(30分) Laravelをインストールし、サーバーを起動。 参考URL: https://readouble.com/laravel/5.8/ja/installation.html https://teratail.com/questions/285110 https://stackoverflow.com/questions/39098717/fatal-error-unable-to-create-lock-file-bad-file-descriptor-9-while-running https://stackoverflow.com/questions/17933882/php-bad-file-descriptor-error 3、実装 HTMLとCSSを同時に書いていく。 header(PC45分)(SP10分) 新規登録ページ(PC70分)(SP10分) ログインページ(PC20分)(SP0分) パスワードリセットリンク(PC15分)(SP0分) パスワードリセット画面(PC10分)(SP0分) 完了ページ(PC10分)(SP5分) 予約確認ページ(PC15分)(SP5分) マイページ(PC45分)(SP0分) 予約ページ(PC5分)(SP5分) 表示するためにコントローラーを通す(10分) 参考URL: https://readouble.com/laravel/5.5/ja/configuration.html https://readouble.com/laravel/5.4/ja/mix.html https://saruwakakun.com/html-css/basic/box-shadow HTML/CSSが完了したので、PHPの処理部分に入る。 usersテーブルの作成(5分) deleted_atのカラムを追加 参考URL: https://qiita.com/miriwo/items/5e5a47ece1b805266246 https://qiita.com/I-201/items/bfb4c216da196247e369 ログイン機能の確認(5分) ログイン後のヘッダー直し(10分) ログアウト後の戻りページ直し(5分) 参考URL: https://teratail.com/questions/259884 https://qiita.com/nekyo/items/d9413d8ae6dc9f3eb05d ログイン処理のエラー文字を赤色にする(5分) ログイン処理のエラー枠を赤色にする(5分) エラーメッセージを日本語にする(5分) 参考URL: https://qiita.com/samuraibrass/items/d71c08e144dbbf98e348 新規登録で確認メールを送信(30分) 参考URL: https://qiita.com/nekyo/items/03e50b4d0dd6f09287d6 https://qiita.com/yutaroshimamura/items/8a89fc57bd3c73a24c32 https://www.sejuku.net/blog/72944 https://stackoverflow.com/questions/50232314/laravel-5-5-missing-required-parameters-for-route-password-request 認証メールを日本語化(60分) 参考URL: https://webplus8.com/laravel-env-attention/ https://eigoswitch.com/eigo-regards#:~:text='Regards'%20%E3%82%92%E8%8B%B1%E8%AA%9E%E3%81%AB%E7%9B%B4%E8%A8%B3,%E3%81%AE%E5%90%8D%E5%89%8D%E3%82%92%E6%9B%B8%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82 https://teratail.com/questions/217183 https://note.com/insectchan/n/n80de3ee6722b 苦労したこと 日本語に設定したが、なかなか反映しないので見落としがあるか何度もチェックすることで時間をかけてしまいました。ただ、その原因はキャッシュが残っていたことだったので、次からはそちらも見逃さず当たりをつけられるようにしたい。 パスワードリセットメールの日本語化(15分) コーチテーブルの作成&seederでのデータ挿入(15分) 時間テーブルの作成&seederでのデータ挿入(15分) レッスン場所テーブル&seederでのデータ挿入(30分) 参考URL: https://stackoverflow.com/questions/59511459/how-to-get-website-url-in-laravel-seeder https://teratail.com/questions/864 https://qiita.com/Otake_M/items/3c761e1a5e65b04c6c0e 苦労したこと レッスン場所のマップをURLで入れる際の型とそれに必要な方法を調べるのに手間取ってしまった。調べたいことをすぐに言葉にできるように常に意識づけをしたい。 予約画面の作成(300分) 参考URL: http://hpscript.com/blog/php%E3%81%A7%E4%BA%88%E7%B4%84%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E4%BD%9C%E3%81%8F%E3%82%8D%E3%81%862%E3%80%80%E4%BA%88%E7%B4%84%E7%94%BB%E9%9D%A2/ https://jqueryui.com/datepicker/ https://teratail.com/questions/31293 https://www.larajapan.com/2019/11/10/npm%E3%81%8B%E3%82%89%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%92%E8%BF%BD%E5%8A%A0/ https://pointsandlines.jp/front-end/javascript/datepicker https://stackoverflow.com/questions/43823295/uncaught-typeerror-datepicker-is-not-a-function-at-htmldocument-anonymo/43823339 https://code-kitchen.dev/html/input-date/ https://takuya0805.hatenadiary.org/entry/20131023/1382505579 https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/date 苦労したこと カレンダーのようなUIがあれば利用者に分かりやすいと思いdatepickerを導入することにしましたが、datepickerが機能せずに苦労しました。初めはjQueryやjQuery-uiが読み込みできていないと思い、読み込み順序を確認したり、CDNで実験してみたりしましたがうまくいきませんでした。。クリックしたらアラートを出すような単純な処理を加えるときちんと反応していたので、そもそもdatepickerに問題があると思いましたが解決できませんでした。そこでinputのdateを使ってカレンダーのように表示し、登録できるようにしました。この一連の作業のため、かなり時間がかかってしまいました。 reservationsテーブルの作成(10分) 予約機能の実装(45分) マイページの実装(180分) 参考URL: https://blog.capilano-fw.com/?p=665 登録済のユーザーしか使えないようにページの表示をルーティングで調整(10分) 不要部分の削除、必要箇所にコメントを入れる(30分) 4、テスト(ローカル) 必要な要件はすべて実装し終えたので、テストをする。テストは単体テストと結合テストの2つを行う。単体テストは境界値テストとブラックボックステストを行う。結合テストでは、ページの遷移が正しいかなど、全体的な動作の確認を行う。 加えて、今回のテスト範囲は、PCは世界的にもっとも使われているGoogle Chrome、スマホはandroidとiOSの最新バージョンでテストをする。スマホのブラウザはSafariとGoogle Chromeにする。 尚、スマホについてはシミュレーターを使う。 単体テストケースの作成(100分) 結合テストケースの作成(10分) 単体テストの実施(240分) 機能名 No. 分類 テスト手順 想定結果 結果1 担当者1 実施日1 新規登録機能 1 異常系 名前欄、メールアドレス欄、パスワード欄、パスワード再入力欄に何も入力せず、登録ボタンを押す。 DBの登録処理は実施されず、名前欄のところに「このフィールドを入力してください」と表示される。 ○ 自分 3/26 2 異常系 名前欄に「test」を入力し、メールアドレス欄、パスワード入力欄、パスワード再入力欄は何も入力せず、登録ボタンを押す。 DBの登録処理は実施されず、メールアドレス欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 3 異常系 名前欄に「test」を入力し、メールアドレス欄に「test@test.com」を入力し、パスワード入力欄、パスワード再入力欄は何も入力せず、登録ボタンを押す。 DBの登録処理は実施されず、パスワード入力欄にパスワードを提案される。 ○ 自分 3/26 4 異常系 名前欄に「test」を入力し、メールアドレス欄に「test@test.com」を入力し、パスワード入力欄に「aaaaaaaa」を入力し、パスワード再入力欄は何も入力せず、登録ボタンを押す。 DBの登録処理は実施されず、パスワード確認欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 5 異常系 名前欄に「test」を入力し、メールアドレス欄に「@test.com」を入力し、パスワード入力欄に「aaaaaaaa」を入力し、パスワード最入力欄に「aaaaaaaa」を入力し、登録ボタンを押す。 DBの登録処理は実施されず、メールアドレス入力欄の下に「「@」の前の文字列を入力してください。「@test.com」は完全なメールアドレスではありません。」と表示される。 ○ 自分 3/26 6 異常系 名前欄に「a」を256文字入力し、メールアドレス欄に「test@test.com」を入力し、パスワード入力欄に「aaaaaaaa」、パスワード再入力欄に「aaaaaaaa」を入力し、登録ボタンを押す。 DBの登録処理は実施されず、名前入力欄に「名前は255文字以下のみ有効です。」の赤文字と該当入力欄が赤色で囲われる。 ○ 自分 3/26 7 異常系 名前欄に「test」を入力し、メールアドレス欄にaを256文字、その後に@a.comというメールアドレスの形式を入力し、パスワード入力欄に「aaaaaaaa」、パスワード再入力欄に「aaaaaaaa」を入力し、登録ボタンを押す。 DBの登録処理は実施されず、メールアドレス入力欄に「メールアドレスは255文字以下のみ有効です。」の赤文字と該当入力欄が赤色で囲われる。 ○ 自分 3/26 8 異常系 名前欄に「test」を入力し、メールアドレス欄に「自分のメールアドレス」と入力し、パスワード入力欄に「aaaaaaaa」を入力し、パスワード再入力欄に「aaaaaaaa」を入力し、登録ボタンを押す。 DBの登録処理は実施されず、エラーメッセージも表示されない。 ○ 自分 3/26 9 異常系 名前欄に「test」を入力し、メールアドレス入力欄に「test@test.com」と入力し、パスワード入力欄に「aaaaaaa」を入力し、パスワード再入力欄に「aaaaaaa」を入力し、登録ボタンを押す。 DBの登録処理は実施されず、パスワード入力欄下に、「パスワードは8文字以上のみ有効です」の赤文字と該当入力欄が赤色で囲われる。 ○ 自分 3/26 10 異常系 名前欄に「test」を入力し、メールアドレス入力欄に「test@test.com」と入力し、パスワード入力欄にaを256文字入力し、パスワード再入力欄にaを256文字入力し、登録ボタンを押す。 DBの登録処理は実施されず、パスワード入力欄下に、「パスワードは255文字以下のみ有効です。」の赤文字と該当入力欄が赤色で囲われる。 ○ 自分 3/26 11 異常系 名前欄に「test」を入力し、メールアドレス入力欄に「test@test.com」と入力し、パスワード入力欄に「aaaaaaaa」と入力し、パスワード再入力欄に「bbbbbbbb」と入力し、登録ボタンを押す。 DBの登録処理は実施されず、パスワード入力欄下に、「パスワードは確認用と一致させてください」の赤文字と該当入力欄が赤色で囲われている。 ○ 自分 3/26 12 正常系 名前欄に「test」を入力し、メールアドレス入力欄「自分のメールアドレス」と入力し、パスワード入力欄に「aaaaaaaa」と入力し、パスワード再入力欄に「aaaaaaaa」と入力し、登録ボタンを押す。 確認メールが送信され、そのリンクをクリックするように案内する画面が表示される。実際に届いたメールをクリックしてDBに登録される。認証されたかどうかの確認は、email_verified_atに記録される。正しく登録されれば、マイページに遷移する。 ○ 自分 3/26 ログイン機能 13 異常系 メールアドレス欄、パスワード欄に何も入力せず、ログインボタンを押す。 ログイン処理は実施されず、メールアドレス入力欄に、「このフィールドを入力してください」と表示される。 ○ 自分 3/26 14 異常系 メールアドレス入力欄に「@test.com」と入力し、パスワード欄に「aaaaaaaa」と入力し、ログインボタンを押す。 ログイン処理は実施されず、メールアドレス入力欄の下に「「@」の前の文字列を入力してください。「@test.com」は完全なメールアドレスではありません。」と表示される。 ○ 自分 3/26 15 正常系 メールアドレス入力欄「自分のメールアドレス」と入力し、パスワード入力欄に「aaaaaaaa」と入力し、っログインボタンを押す。 ログインが許可され、マイページ画面に遷移する。 ○ 三吉 3/26 パスワード変更機能 16 異常系 メールアドレス欄に「test@test.com」を入力し、送信ボタンを押す。 「ユーザーは存在しません。」と入力欄の下に表示される。 ○ 自分 3/26 17 異常系 メールアドレス入力欄に何も入力せず送信ボタンを押す。 メールアドレス入力欄の下に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 18 異常系 メールアドレス欄に「@test.com」を入力し、送信ボタンを押す。 メールアドレス入力欄の下に「「@」の前の文字列を入力してください。「@test.com」は完全なメールアドレスではありません。」と表示される。 ○ 自分 3/26 19 正常系 メールアドレス入力欄「自分のメールアドレス」と入力し、送信ボタンを押す。 確認メールが送信され、そのリンクをクリックし、パスワード更新画面に遷移する。そこで、メールアドレスは「自分のメールアドレス」、パスワードは「bbbbbbbb」、パスワード確認は「bbbbbbbb」を入力し、更新する。 ○ 自分 3/26 予約機能 20 異常系 何も入力せず予約ボタンを押す DBの登録処理はされず、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 21 異常系 日時(2021/4/4)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時以外の入力部分の枠が赤くなり、入力欄の下に「~必須です。」と表示される。 ○ 自分 3/26 22 異常系 時間(9:00~10:00)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 23 異常系 コーチ(ホセ・トドロギ)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 24 異常系 レッスン場所(日吉ゴルフ練習場)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 25 異常系 日時(2021/4/4)、時間(9:00~10:00)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時、時間以外の入力部分の枠が赤くなり、入力欄の下に「~は必須です。」と表示される。 ○ 自分 3/26 26 異常系 日時(2021/4/4)、コーチ(ホセ・トドロギ)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時、コーチ以外の入力部分の枠が赤くなり、入力欄の下に「~は必須です。」と表示される。 ○ 自分 3/26 27 異常系 日時(2021/4/4)、レッスン場所(日吉ゴルフ練習場)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時、レッスン場所以外の入力部分の枠が赤くなり、入力欄の下に「~は必須です。」と表示される。 ○ 自分 3/26 28 異常系 時間(9:00~10:00)、コーチ(ホセ・トドロギ)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 29 異常系 時間(9:00~10:00)、レッスン場所(日吉ゴルフ練習場)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 30 異常系 コーチ(ホセ・トドロギ)、レッスン場所(日吉ゴルフ練習場)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 31 異常系 日時(2021/4/4)、時間(9:00~10:00)、コーチ(ホセ・トドロギ)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時、時間、コーチ以外の入力部分の枠が赤くなり、入力欄の下に「レッスン場所は必須です。」と表示される。 ○ 自分 3/26 32 異常系 日時(2021/4/4)、時間(9:00~10:00)、レッスン場所(日吉ゴルフ練習場)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時、時間、レッスン場所以外の入力部分の枠が赤くなり、入力欄の下に「コーチは必須です。」と表示される。 ○ 自分 3/26 33 異常系 時間(9:00~10:00)、コーチ(ホセ・トドロギ)、レッスン場所(日吉ゴルフ練習場)を入力し、他は何も入力せず予約するボタンを押す。 DBの登録処理はされず、日時欄に「このフィールドを入力してください」と表示される。 ○ 自分 3/26 34 正常系 日時(2021/4/4)、時間(9:00~10:00)、コーチ(ホセ・トドロギ)、レッスン場所(日吉ゴルフ練習場)を入力し、予約するボタンを押す。 DBの登録処理が行われ、reservationテーブルに予約した内容が表示される。 ○ 自分 3/26 結合テストの実施(30分) 機能名 No. 分類 テスト手順 想定結果 結果1 担当者1 実施日1 予約機能 1 正常系 日時(2021/4/4)、時間(9:00~10:00)、コーチ(ホセ・トドロギ)、レッスン場所(日吉ゴルフ練習場)を入力し、予約するボタンを押す。 DBの登録処理が行われ、マイページに遷移しマイページに先ほど予約した内容が表示される。 ○ 自分 3/26 2 正常系 マイページの予約一覧にあるGoogleMapのリンクをクリックし、日吉ゴルフ練習場、ゴルフ・コンフォート、バーディーゴルフ、それぞれ正しい情報に遷移する。 日吉ゴルフ練習場(名古屋市中村区岩塚神明西)、ゴルフ・コンフォート(名古屋市天白区中砂町549)、バーディーゴルフ(愛西市落合町上河原1510-1)の正しい地図情報が表示される。 ○ 自分 3/26 参考URL: https://xera.jp/entry/iphone-android-share https://www.atmarkit.co.jp/ait/articles/0607/22/news014.html https://qiita.com/unsoluble_sugar/items/f39bb5afae60f51ea7a4 5、本番デプロイ Xサーバーにデプロイする。(60分) 参考URL: https://naoya-ono.com/blog/deploy-laravel-xserver/ https://www.xserver.ne.jp/manual/man_server_htaccess.php バリュードメインでドメインを購入し、ネームサーバを設定。 Githubにソースコードをアップ。 各種設定をする。 6、テスト(本番) 本番テスト(30分) 本番環境できちんと動作するか確認する。 機能名 No. 分類 テスト手順 想定結果 結果1 担当者1 実施日1 結果2 担当者2 実施日2 新規登録機能 1 正常系 名前欄に「test」、メールアドレス入力欄「自分のメールアドレス」と入力し、パスワード入力欄に「aaaaaaaa」と入力し、パスワード再入力欄に「aaaaaaaa」と入力し、登録ボタンを押す。 確認メールが送信され、そのリンクをクリックするように案内する画面が表示される。実際に届いたメールをクリックしてDBに登録される。認証されたかどうかの確認は、email_verified_atに記録される。正しく登録されれば、マイページに遷移する。 × 自分 3/29 ○ 自分 3/29 ログイン機能 2 正常系 メールアドレス入力欄「自分のメールアドレス」と入力し、パスワード入力欄に「aaaaaaaa」と入力し、ログインボタンを押す。 ログインが許可され、マイページ画面に遷移する。 ○ 自分 3/29 パスワード変更機能 3 正常系 メールアドレス入力欄「自分のメールアドレス」と入力し、送信ボタンを押す。 確認メールが送信され、そのリンクをクリックし、パスワード更新画面に遷移する。そこで、「bbbbbbbb」を入力し、更新する。 ○ 自分 3/29 予約機能 4 正常系 日時(2021/4/4)、時間(9:00~10:00)、コーチ(ホセ・トドロギ)、レッスン場所(日吉ゴルフ練習場)を入力し、予約するボタンを押す。 DBの登録処理が行われ、マイページに遷移しマイページに先ほど予約した内容が表示される。 ○ 自分 3/29 5 正常系 マイページの予約一覧にあるGoogleMapのリンクをクリックし、日吉ゴルフ練習場、ゴルフ・コンフォート、バーディーゴルフ、それぞれ正しい情報に遷移する。 日吉ゴルフ練習場(名古屋市中村区岩塚神明西)、ゴルフ・コンフォート(名古屋市天白区中砂町549)、バーディーゴルフ(愛西市落合町上河原1510-1)の正しい地図情報が表示される。 ○ 自分 3/29 参考URL: https://qiita.com/takuma-jpn/items/f4e23bed778b17b52e36 7、まとめ 全体として1725分。1人日を8時間とした場合は、3.6人日での完成でした。 現状の予約システムはユーザーに日程を確認してもらって予約する仕組みになっているため、これをシステム側で制御して間違いがないように予約ができるようにしてみたい。また、1人3コマまで予約できるようにしたり、レッスン日が過ぎたら自動で日程をマイページ側から消したり、予約の変更機能だったりをつけてより本格的にしてみたい。
- 投稿日:2021-04-05T21:59:57+09:00
[laravel]NEWS APIを使いデータを取得してみた
はじめに この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。 今回は、APIを扱う練習としてlaravelをベースにGuzzleを使い、NEWS APIからニュースを取得してみました。 間違いなどがございましたら、ご指摘のほどよろしくお願い致します。 事前準備 その1: NEWS APIにて,APIKeyを取得して下さい。 下記画像の通り、各項目を入力後Submitを押すと取得できます。 その2: Guzzleをインストール composer require guzzlehttp/guzzle 手順 取得したAPIkeyを.envファイルに環境変数として設定 NEWS API用のconfigファイルを作成 データを取得し表示する為のルーティングを作成 ルーティングで設定したコントローラーとメソッドを作成 bladeに連想配列として値を渡し取得したデータを表示 1.取得したAPIKeyを.envファイルに環境変数として設定 /.env NEWS_API_KEY=取得したAPIKeyを記述 NEWS_API_URL='https://newsapi.org/v2/' 2.API用のconfigファイルを作成 config/newsapi.php <?php return [ 'news_api_url' => env('NEWS_API_URL', null), 'news_api_key' => env('NEWS_API_KEY', null), ]; 解説 コントローラーのメソッド内でAPIのurlを設定する時に、config('newsapi.news_api_url')のように記述して使用します。'news_api_key'も同様です。 3.データを取得し表示する為にルーティングを作成 routes/web.php <?php Route::get('/api', 'ApiController@index'); 4.ルーティングで設定したコントローラーとメソッドを作成 ApiController.php <?php namespace App\Http\Controllers; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7; class ApiController extends Controller { public function index() { try { $url = config('newsapi.news_api_url') . "top-headlines?country=us&category=business&apiKey=" . config('newsapi.news_api_key'); $method = "GET"; $count = 15; $client = new Client(); $response = $client->request($method, $url); $results = $response->getBody(); $articles = json_decode($results, true); $news = []; for ($id = 0; $id < $count; $id++) { array_push($news, [ 'name' => $articles['articles'][$id]['title'], 'url' => $articles['articles'][$id]['url'], 'thumbnail' => $articles['articles'][$id]['urlToImage'], ]); } } catch (RequestException $e) { echo Psr7\Message::toString($e->getRequest()); if ($e->hasResponse()) { echo Psr7\Message::toString($e->getResponse()); } } return view('index', compact('news')); } } 解説1 use GuzzleHttp\Psr7; use GuzzleHttp\Exception\RequestException; try{ //略 }catch (RequestException $e) { echo Psr7\Message::toString($e->getRequest()); if ($e->hasResponse()) { echo Psr7\Message::toString($e->getResponse()); } try catchを使い、リクエストの転送中にスローされる可能性のあるすべての例外をキャッチするようにしています。下記の説明文はGuzzle公式ドキュメントを翻訳して載せています。 ネットワークエラー(接続タイムアウト、DNSエラーなど)が発生した場合、GuzzleHttp\RequestExceptionがスローされます。この例外は、GuzzleHttpException\TransferExceptionを継承しています。この例外をキャッチすると、リクエストの転送中にスローされる可能性のあるすべての例外がキャッチされます。 参考:Guzzle Docs Quickstart 解説2 $url = config('newsapi.news_api_url') . "top-headlines?country=us&category=business&apiKey=" . config('newsapi.news_api_key'); $method = "GET"; $count = 15; $urlと$methodは、後ほど$response = $client->request($method, $url);のように、リクエストを送る際にメソッドとurlとして使用するので設定しておきます。 今回は、$urlを日本のビジネスというカテゴリのヘッドラインニュースを取得するように設定しています。また、先ほど設定したconfigファイルのkey('news_api_url'と'news_api_key')も使用します。 urlの設定方法は、下記の画像のようにNEWS APIの公式サイトに書かれているurlを参考にしています。 $methodはNEWS APIを利用してデータを取得する為にGETメソッドを使用します。 $countは表示件数を15としたい為、設定しています。 解説3 $client = new Client(); $response = $client->request($method, $url); 今回は、コードを簡略化して書きたいと思ったので、Guzzle7が提供しているGuzzleHttp\Psr7\Uriクラスを使用した、インターフェースの実装を試みました。 参考:Guzzle7 Request URI $response = $client->request('GET', 'http://httpbin.org/get?q=foo'); 上記コードの説明 The request URI is represented by a Psr\Http\Message\UriInterface object. Guzzle provides an implementation of this interface using the GuzzleHttp\Psr7\Uri class. When creating a request, you can provide the URI as a string or an instance of Psr\Http\Message\UriInterface. 解説4 $results = $response->getBody(); GETリクエストのレスポンスのボディをgetBody()メソッドで取得しています。 下記リンク先のコードを参考に設定しました。 $body = $response->getBody(); echo $body; // Cast to a string: { ... } 参考:Guzzle7 Responses Body 解説5 $articles = json_decode($results, true); NEWS APIからレスポンスとして渡ってくるデータはJSON形式なので、json_decode()メソッドを使うことでJSONを連想配列にしています。 解説6 $news = []; for ($id = 0; $id < $count; $id++) { array_push($news, [ 'name' => $articles['articles'][$id]['title'], 'url' => $articles['articles'][$id]['url'], 'thumbnail' => $articles['articles'][$id]['urlToImage'], ]); } 先ほど、json_decode()メソッドを使いJSON形式のデータを連想配列に変換したと思います。 dd($articles);で中身を見てみると下記のように多次元連想配列となっています。 従って、array_push()メソッドで使いたいkey(データ)を配列に追加するようにします。 流れとしては、$news = [];で空の配列を作り、繰り返し処理で先ほど作成した$count変数を使い、表示件数(繰り返される回数)を指定、そしてarray_push()メソッドを使い、対象となる配列を第一引数に、追加する連想配列を第二引数で作成することで空の配列である$news変数にデータが連想配列として格納されます。 5.bladeに連想配列として値を渡し取得したデータを表示 前提として、コントローラーのメソッド内でreturn view('index', compact('news'));を記述しデータ(連想配列)をbladeに渡します。 そして、下記のように渡ってきた連想配列($news)をforeach文で展開して表示します。 <body> <div class="container "> @foreach($news as $data) <div class="card-body pt-0 pb-2"> <h3 class="h5 card-title"> <a href="{{$data['url']}}">{{$data['name']}}</a> </h3> <div class="card-text"> <img src="{{$data['thumbnail']}}"> </div> </div> @endforeach </div> 結果 レイアウトは整えていませんが、下記のように表示できれば成功です。 おわりに ひとまずエラーなくデータを取得することができたので、次回はこのAPIを活用してニュースアプリを作成してみたいと思います。 最後までお読み頂きありがとうございました。 参考文献 phpマニュアル Guzzle7 公式ドキュメント Guzzle GitHub NEWS API
- 投稿日:2021-04-05T21:48:31+09:00
Laravel 認証済みユーザーの取得方法
公式ドキュメント Laravel 8.x 認証 環境 PHP: 8.0.2 Laravel: 8.28.1 認証済みユーザー取得 Laravelで認証済みユーザーを取得する方法がいくつかあるのでご紹介します。 Authファサード use Illuminate\Support\Facades\Auth; // 現在認証しているユーザーを取得 $user = Auth::user(); // 現在認証しているユーザーのIDを取得 $id = Auth::id(); authヘルパー // 現在認証しているユーザーを取得 $user = auth()->user(); // 現在認証しているユーザーのIDを取得 $id = auth()->id(); Requestインスタンス(メソッドインジェクション) app/Http/Controllers/FlightController.php <?php declare(strict_types=1); namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\Response; final class FlightController extends Controller { /** * @param Request $request * @return Response */ public function update(Request $request): Response { $user = $request->user() // ... } } Requestインスタンス(コンストラクタインジェクション) 前述まで紹介したものの中ではこのコンストラクタインジェクションのパターンが好きです。 app/Http/Controllers/FlightController.php <?php declare(strict_types=1); namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\Response; final class FlightController extends Controller { public function __construct(private Request $request) { } /** * @return Response */ public function update(): Response { $user = $request->user() // ... } } リポジトリー層に認証済みユーザー取得する処理を実装する 公式で紹介されている方法はいずれもLaravelフレームワークに依存してしまいます。 フレームワークへの依存を減らすためにリポジトリー層を用意して実装する方法をご紹介します。 app/Repository/AuthenticatedUser.php [新規] app/Repository/LaravelAuthenticatedUser.php [新規] app/Providers/AppServiceProvider.php [編集] app/Http/Controllers/FlightController.php [編集] app/Repository/AuthenticatedUser.php [新規] 新しく AuthenticatedUser インターフェースを定義します。 app/Repository/AuthenticatedUser.php <?php declare(strict_types=1); namespace App\Repository; use App\Models\User; interface AuthenticatedUser { public function user(): User; public function id(): int; } app/Repository/LaravelAuthenticatedUser.php [新規] AuthenticatedUser インターフェースを実装した LaravelAuthenticatedUser クラスを作成します。 app/Repository/LaravelAuthenticatedUser.php <?php declare(strict_types=1); namespace App\Repository; use App\Models\User; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Http\Request; final class LaravelAuthenticatedUser implements AuthenticatedUser { public function __construct(private Request $request) { } /** * @return User * @throws AuthorizationException */ public function user(): User { $user = $this->request->user(); if ($user === null) { throw new AuthorizationException('ここから先は通さん!!!'); } return $user; } /** * @return int * @throws AuthorizationException */ public function id(): int { $id = $this->request->user()?->id; if ($id === null) { throw new AuthorizationException('ここから先は通さん!!!'); } return $id; } } app/Providers/AppServiceProvider.php [編集] AuthenticatedUser インターフェースに対応する LaravelAuthenticatedUser 実装するクラスのバインド設定をサービスプロバイダーで行います。 app/Providers/AppServiceProvider.php <?php declare(strict_types=1); namespace App\Providers; use App\Repository\AuthenticatedUser; use App\Repository\LaravelAuthenticatedUser; use Illuminate\Support\ServiceProvider; final class AppServiceProvider extends ServiceProvider { public array $bindings = [ AuthenticatedUser::class => LaravelAuthenticatedUser::class, ]; } app/Http/Controllers/FlightController.php [編集] AuthenticatedUser インターフェースをコントローラ側で使ってみます。 app/Http/Controllers/FlightController.php <?php declare(strict_types=1); namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\Response; final class FlightController extends Controller { public function __construct(private AuthenticatedUser $authenticatedUser) { } /** * @return Response */ public function update(): Response { dump($this->authenticatedUser->user()); dump($this->authenticatedUser->id()); // ... } } こんな感じでLaravelフレームワーク(ファサードやヘルパー)ではなくAuthenticatedUserインターフェース(抽象)に依存したコードが書けました?
- 投稿日:2021-04-05T20:52:21+09:00
【Laravel】ZipArchiveを使ってS3の画像をまとめてzip化する
はじめに 業務で結構詰まってしまったので、今後のためのメモ。 また、ローカルでは動いたが、ステージングでは動かない問題にも直面したので、 それの対応策についてもまとめる。 環境 Laravelは7を使用。パッケージ管理はComposer プロジェクト開始時は8が出た直後だったので、7使ってました。 ローカル いたって普通の windows 10 pro Edition。 ローカルの環境にAWSのIAMロールは付けられないので、 開発中だけ、S3を操作できる最低限のIAMロールを持ったユーザを作成し、 アクセスキーIDや、シークレットアクセスキーを発行して使用する。 ステージング AWS EC2を使用。OSは Amazon Linux2。 インスタンス自体にS3を操作できる最低限のIAMロールを持たせており、 アクセスキーIDや、シークレットアクセスキーを使わない運用をする(予定) やること チェックボックスで選択された複数の画像をS3から取得し、zip化してダウンロードする。 この記事ではフロント側の処理は書かず、サーバ側(Laravel)の処理について書きます。 コード S3への接続準備 S3に接続するためのコードです。 アクセスキーID・シークレットアクセスキーを使用するローカルと、 EC2のIAMロールを使用するステージングで少し異なります。 $bucket = config('filesystems.disks.s3.bucket'); $imgDir = "path/to/hogehoge"; // S3に接続するための情報 $s3Config = [ 'version' => 'latest', 'region' => config('filesystems.disks.s3.region'), ]; // ローカル環境用: IAMロールを使えないので情報を追加する if (config('app.env') === 'local') { $s3Config['credentials'] = [ 'secret' => config('filesystems.disks.s3.secret'), 'key' => config('filesystems.disks.s3.key'), ]; } $s3Client = new S3Client($s3Config); ローカル用で使っている、アクセスキーID・シークレットアクセスキーを設定して接続する方法は検索すればたくさん出てきます。 検索に困ることはあまりないでしょう。 問題はIAMロールを使う方法です。 こちらの場合は $s3Config 変数の連想配列の credentials 項目が丸々ありません。 この項目がない場合の動きは、公式ドキュメントによると下記の通りです credentials オプションを指定しない場合、SDK は環境からの認証情報のロードを以下の順序で試行します。 1.環境変数から認証情報をロードする 2.credentials.ini ファイルから認証情報をロードする 3.IAM ロールから認証情報をロードします。 3番目にIAMロールの認証が使われると書いています。 credentialsをつけてしまうと、今回のステージング環境ではS3に接続できなくて動きません。 例え .env で対応する部分を空文字にしていようがエラーになってしまいます。 Storage::cloud()->get('/path/to') みたいにStorageファサードを使う場合は、.env の対応部分を空にしておけばOKなのですが、S3Clientクラスを使う場合はcredentialsオプションごと無くす必要があるのでごっちゃにならないようにしましょう。マジで。 画像取得のコマンドをまとめる 取得する画像分の情報をDBから取得し、その数だけ取得コマンドを生成します。 $imgs = []; // DBから取得する画像の情報を取得 // zipファイルの生成場所 $fileName = 'result.zip'; $filePath = storage_path('app/' . $fileName); // 画像取得コマンド $commands = []; foreach ($imgs as $img) { $key = $imgDir . $img['name']; $commands[] = $s3Client->getCommand( 'GetObject', [ 'Bucket' => $bucket, 'Key' => $key, ] ); } // 作成したコマンドの配列を実行 $command_pool_batch = CommandPool::batch($s3Client, $commands); $command 配列にはS3にあるファイルを取得するコマンドが格納されます。 'GetObject' ファイルを取得する。という命令 'Bucket' S3に生成したバケット 'key' バケット内にある、取得したい画像のパス この部分をforeachループで変化させ、選択した画像の取得コマンドを生成 最後に CommandPool::batchで、生成したコマンドを実行させます。 command_pool_batch 変数には、取得された結果が入っているので、あとはこの中身をzipに入れてDLさせます。 zip化して、DL ZipArchiveクラスを使用します。 先ほども書きましたが、command_pool_batch 変数に結果が入っているので、これをループさせます。 // zipファイル作成 $zip = new ZipArchive(); $isOpen = $zip->open($filePath, ZipArchive::CREATE | ZipArchive::OVERWRITE); // 成功時はbool型なので、型のチェックまで行う if ($isOpen === true) { foreach ($command_pool_batch as $key => $value) { // 取得できなかったらS3Exceptionが格納される if (strpos(get_class($value), 'S3Exception') !== false) { Log::warning('fail get photo'); continue; } header("Content-Type: {$value['ContentType']}"); // ファイル名を指定(しないとS3内のフルパスが使われるらしい) $fileName = $imgs[$key]['name']; $zip->addFromString($fileName, $value['Body']); } $zip->close(); ob_end_clean(); } // レスポンスヘッダー $headers = [ 'Content-Type' => 'application/zip', 'Content-Disposition' => 'attachment' ]; return response() ->download($filePath, $fileName, $headers) ->deleteFileAfterSend(true); foreach文で $command_pool_batch as $key => $value としていますが、$key にはインデックス番号が入ってきます。具体的な取得結果は $value の方です。 addFromString を使ってどんどんzipに画像の情報を追加していきます。 全て追加し終えたら、closeしてフロント側に渡しましょう。
- 投稿日:2021-04-05T17:22:20+09:00
Laravelで404, 500ステータスコードを返すシンプルなAPI実装
仕事の関係で、Laravel+Vueの開発をやっています。Laravelを使うのは初めてなので、学んだものを記録します。 学んだこと Web APIの基本作りです。 今回はステータスコードのみ、非常にシンプルなレスポンスを返すWeb APIを作成してみました。 手順としては、 - API Controllerの作成 - Routeの設定 以上です。 API Controllerの作成 app/Http/Controllersの配下にTestHttpStatus.phpを作成しました。 e404, e500という二つの関数を作成し、それぞれ400, 500のステータスコードを設定します。 use App\Http\Controllers\Controller; use Illuminate\Http\Request; class TestHttpStatus extends Controller { public function e400(Request $request) { return response()->json([], 404, ['Content-Type' => 'application/json'], JSON_UNESCAPED_UNICODE); } public function e500(Request $request) { return response()->json([], 500, ['Content-Type' => 'application/json'], JSON_UNESCAPED_UNICODE); } } Route routes/api.phpにAPIのルートを追加する。 use App\Http\Controllers\TestHttpStatus; ... Route::get('test_e404', [TestHttpStatus::class, 'e404'])->name('e404'); Route::get('test_e500', [TestHttpStatus::class, 'e500'])->name('e500'); http://localhost/test_e404にアクセスすると400エラーが発生します。 http://localhost/test_e500にアクセスすると500エラーが発生します。 応用 404, 500エラーをテストしたい時に使えると思います。 また、Routeの部分ですが、routes/api.phpではなく、routes/web.phpにルートに設定するとカスタマイズの404, 500ページも検証できると思いました。 次回のチャンスがある際にメモします。
- 投稿日:2021-04-05T13:24:44+09:00
[Laravel]Factoryとfakerでダミーデータを作成する方法
はじめに こんにちは! Factoryとfakerを使ってダミーデータを大量に作成したので、使い方を書きます。 環境 Laravel: 6.8 MySQL: 8.0 手順 fakerの言語設定 まず、はじめにダミーデータの言語を設定します。 デフォルトで英語になっているので、日本語に変更します。 config/app.php 'faker_local' => 'ja_JP' // 変更 ファイル作成 次にモデル・マイグレーション・ファクトリーを作成します。 ターミナルでphp artisan make:model Models\Test -m -fのコマンドを入力します。 テーブルの作成 まず、DBにテーブルとカラムを作成します。 先ほどのコマンドでTestモデルに紐づいたマイグレーションファイルが作成されているので、その中にコードを追加します。 database/migrations/作成日_create_tests_table.php public function up() { Schema::create('tests', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name', 50); $table->string('user_name', 50); $table->string('sex', 1); $table->string('post_code', 7); $table->string('address'); $table->string('email'); $table->string('tel'); $table->string('password'); $table->string('text', 100); $table->integer('number'); $table->timestamps(); }); } 今回はこんな感じで適当なカラムでテーブルを作成します。 Factoryの作成 ここが本題です。 Factoryファイルの中にダミーデータを作成する際のルールみたいのを記述します。 database/factories/TestFactory.php use App\Models\Dummy; use Faker\Generator as Faker; $factory->define(Test::class, function (Faker $faker) { return [ 'name' => $faker->name(), // 名前 姓名 'user_name' => $faker->unique()->userName(), // ユーザー名 'sex' => $faker->randomElement(['男', '女']), // 配列内の文字をランダムに出力 今回は男or女 'post_code' => $faker->regexify('[1-9]'), // 正規表現で郵便番号7桁を出力 'address' => $faker->address(), // 住所 郵便番号も 'email' => $faker->email(), // メールアドレス 'tel' => $faker->phoneNumber(), // 電話番号 'password' => $faker->password(), // パスワード 'text' => $faker->realText(20), // ランダムに日本語文を20文字で出力 'number' => $faker->numberBetween(10, 100) // 10~100の数字をランダムに出力 ]; }); こんな感じでテーブルのカラムに合わせて、作成して欲しいデータを追加します。 seederファイルの作成 factoryができたらseederファイルを作ります。 database/seeds/TestTableSeeder.php public function run() { factory(Test::class, 50)->create(); } 先ほどのfactoryを元に50件のダミーデータを作成してもらいます。 あとはDatabaseSeeder.phpに登録します。 title=DatabaseSeeder.php public function run() { $this->call(TestTableSeeder::class); } 実行 ここまでできたら、あとはphp artisan migrate --seedもしくはphp artisan migrate:fresh --seedを実行します。 エラーなく終えて、ダミーデータが作成されていれば無事完了です。 最後に 大量のダミーデータ作れるから、csvの扱いもまとめてみるかな。。 あと、公式にいい感じのfakerチートシートみたいのあればいいな。。 参考 シーダーについて
- 投稿日:2021-04-05T11:15:11+09:00
他人のLaravelのプロジェクトの動かし方
他人のLaravelのプロジェクトを git clone やダウンロードでローカルに落として動かすことがあるのでその方法を紹介する。 外部ファイルのインストール $ composer update まず、目的のプロジェクトまで移動して、CLIで必要なライブラリを上記コマンドで取り入れる。 .envファイルの修正 マイグレーションファイル等を書き換える場合は .env のファイルを書き換える必要がある。 特にDBの設定部分はここによって違うので自身の環境に合わせなければならない。 .env DB_CONNECTION=DBの種類 DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=データベース名 DB_USERNAME=ユーザー DB_PASSWORD=パスワード 時々 .env のファイルが反映されない時があるのでその時はこちらの記事を参考にしたらうまく参照させることができました。 https://qiita.com/yukke7624/items/14f29d126e38a7d86646 マイグレーション $ php artisan migrate:fresh このコマンドで新たにマイグレーションを行う。 また、ローカルサーバーも下記コマンドで立ち上げられる。 $ php artisan serve
- 投稿日:2021-04-05T09:45:35+09:00
Laravel Migration - Enum型カラムのオプションの変更方法
実現したいこと 実現したいことは、Enum型カラムのオプションを変更することです。 例) 変更前のusersテーブル Field Type Length id BIGINT 20 name VARCHAR 255 type ENUM 'member','cancel' 変更後のusersテーブル Field Type Length id BIGINT 20 name VARCHAR 255 type ENUM 'member','cancel','recess' ENUM型のtypeカラムのオプションはmember(会員)、cancel(退会)が存在します。このオプションにrecess(休会)を追加したいと思います。 実現方法 *私のLaravelのバージョンは5.8.36です。 変更用のマイグレーションファイルを作成します。 $ php artisan make:migration change_column_type_users_table --table=users 作成されたマイグレーションファイルを下記のように記述します。 database/migrations/2021_04_05_183257_change_column_type_users_table.php <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class ChangeColumnTypeUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { DB::statement("ALTER TABLE users MODIFY type ENUM ('member', 'cancel', 'recess')"); } /** * Reverse the migrations. * * @return void */ public function down() { DB::statement("ALTER TABLE users MODIFY type ENUM ('member', 'cancel')"); } } マイグレーション実行 $ php artisan migrate 以上です。 ちなみに下記のような記述では変更できません。理由は、DBAL 2.9.2は列挙型データ型をサポートしていないからだそうです。 Schema::table('users', function (Blueprint $table) { $table->enum('type', ['member', 'cancel', 'recess'])->change(); }); 参考 Laravel Migration - Update Enum Options MySQL で ERROR 1265 (01000): Data truncated for column 'xxxxx' at row 1 みたいなエラーが出たとき
- 投稿日:2021-04-05T04:21:29+09:00
Laravel私的まとめ
Laravel Laravel 8 概要 テストすることで学習定着すると言ってたので 目的 きわめる routing ルーティングとは、URLと、コントローラーなどの対応を指す。 具体的な記述は routes/*.php に記述されている。 nginx設定 きれいなURL を採用するためのnginx設定 └example.com/a で、aControllerを見に行くための設定 location / { index index.php index.htm index.html; try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_split_path_info ^(.+\/php)(/.+)$; fastcgi_pass php-fpm:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } .env 環境設定ファイル。DB, memcache, redisなどの設定。 app自体、ログ、AWS、mail、session、pusher も // TODO migrationファイル作成 artisanでファイルを作成する。 (Flightはサンプルクラス名) ./artisan make:migration Flight [-mfsc] # -mfsc means migration, factory, seeder, controller ファイルを編集して、好きなテーブルレイアウトにする Schema::create('テーブル', function (Blueprint $table) { $table->id(); $table->string('name', 50); // 追加 $table->timestamps(); }); migration実行 ./artisan migrate migration全戻し ./artisan migrate:reset model作成 ./artisan make:model ${モデル名}