20211012のlaravelに関する記事は5件です。

【Laravel】バージョンを確認するときのコマンド

はじめに 現在自分が使っているLaravelのバージョンを確認する方法を見ていきましょう。 Laravelのバージョン確認方法 ターミナル php artisan --version ターミナル php artisan -V Laravel Framework 5.8.38のようにバージョンが表示されればOKです!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel/ui で Vue をインストールした際のエラー対処備忘録

エラー composer require laravel/uiでパッケージを追加して、php artisan ui vueでベースを作成。 その後、npm install npm run devを実行した際に、以下のようなエラーが発生しました。 [webpack-cli] Error: Cannot find module 'webpack/lib/rules/DescriptionDataMatcherRulePlugin' Require stack: - D:\110_LaravelProject\CasualMeetingV2\node_modules\vue-loader\lib\plugin-webpack5.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\vue-loader\lib\plugin.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\vue-loader\lib\index.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\laravel-mix\src\components\Vue.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\laravel-mix\src\components\ComponentRegistrar.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\laravel-mix\src\Mix.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\laravel-mix\setup\webpack.config.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\webpack-cli\lib\webpack-cli.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\webpack-cli\lib\bootstrap.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\webpack-cli\bin\cli.js - D:\110_LaravelProject\CasualMeetingV2\node_modules\webpack\bin\webpack.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15) at Function.Module._load (internal/modules/cjs/loader.js:745:27) at Module.require (internal/modules/cjs/loader.js:961:19) at require (D:\110_LaravelProject\CasualMeetingV2\node_modules\v8-compile-cache\v8-compile-cache.js:159:20) at Object.<anonymous> (D:\110_LaravelProject\CasualMeetingV2\node_modules\vue-loader\lib\plugin-webpack5.js:6:42) at Module._compile (D:\110_LaravelProject\CasualMeetingV2\node_modules\v8-compile-cache\v8-compile-cache.js:192:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) at Module.load (internal/modules/cjs/loader.js:937:32) at Function.Module._load (internal/modules/cjs/loader.js:778:12) at Module.require (internal/modules/cjs/loader.js:961:19) { code: 'MODULE_NOT_FOUND', requireStack: [ 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\vue-loader\\lib\\plugin-webpack5.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\vue-loader\\lib\\plugin.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\vue-loader\\lib\\index.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\laravel-mix\\src\\components\\Vue.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\laravel-mix\\src\\components\\ComponentRegistrar.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\laravel-mix\\src\\Mix.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\laravel-mix\\setup\\webpack.config.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\webpack-cli\\lib\\webpack-cli.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\webpack-cli\\lib\\bootstrap.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\webpack-cli\\bin\\cli.js', 'D:\\110_LaravelProject\\CasualMeetingV2\\node_modules\\webpack\\bin\\webpack.js' ] } これは、vue-loaderが古いせいで発生しているようです。 対処法 以下コマンドを実行して、再度npm run devを実行 npm i vue-loader
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【個人開発】駆け出しエンジニアが個人開発する時に迷わないようにするためのサービス

はじめに この度、「Web Service Hub」というWebアプリケーションを開発しました!今回はこのWebアプリケーションの解説・紹介をするために記事を書きました!これから、「何かサービスを作りたい!」「どうやったら作れるの?」とか思っている方におススメです。 Web Service Hub とは個人でWebサービスを開発している方のためのコミュニティサービスです。サービスを登録したり、みんなのサービスを見てWebサービスの開発を学んで品質向上を目指す場です。 URL ➡ https://web-service-hub.herokuapp.com/ GitHub ➡ https://github.com/kapureka6174/developHelper スマホからの閲覧も対応しています。 「ログイン画面」からゲストログインできますので気になる方はご使用ください。 作成した人 地方国公立文系の三年生でWebエンジニアになるため独学で勉強中 好きなことはプログラミング(React,Vue,Laravel)、デザイン(Canvaよく使います)、音楽(しゃろうさん、becoさんが好きです) NewsPicksなどの記事や番組を見たりして社会問題や会社についてあれこれ考えるのが好きです。 最近はハマっている本は「絶対内定2023 自己分析とキャリアデザインの描き方」(これを読むと人生のモチベが上がるので、特に就活生の方は読んでみてください!) 目次は以下のとおりです。 1. どんなWebアプリなの?【概要・機能】 2. どうやって作ったの?【技術】 3. どうやって勉強したの? 1. どんなWebアプリなの?【概要・機能】 まず、どんなアプリを作ったか?知りたい人は見ていってください。 (1)概要 (2)使い方・画面 (3)機能一覧 (1)概要 冒頭でも示した通り、Web Service Hub は個人でWebサービスを開発している方のためのコミュニティサービスです。 「こんなサービスつくりたい!」っていう人(構想、アイデアだけでも全然OK!!) 「このサービス作ったよ!みんな使ってみて!」という人(デプロイしてるかは問いません) 「駆け出しエンジニアの人はどうやってwebサービス作ってんの?」っていう人 こういう人たちが集まって、サービスを登録したり、「これいいね!」とか、「こういう技術選択すればいいのか!」、「こんな機能いいんじゃない?」みたいに、コメントし合ったりすることを通して、Webサービスがどのように作られているのかを見てWebサービスの開発のやり方を学んでエンジニアとしての質の向上を目指す場として作りました! 開発に至った経緯 私は文系でプログラミングはもちろん、コンピューターサイエンス的なものの素養は全くありませんでした。また、文系学部にいると周りにエンジニアを志望する学生はほとんどいませんでした。(地方かつ、近くの地元に就職したいと考えている人が多いことも原因だと思いますが・・・) そこで、私自身が抱えていた問題は主に以下の内容でした。 どんなサービスを作ったらいいのか分からない 一通り学んだ後に個人開発しようとしてもどこから手を付けるべきか分からない 周りにプログラミングが分かる人がいないためモチベーションが続かない 以上の3つの問題を解決したいと思っていました。 詳しい内容やどういう風にサービスの概要を決めていったかは以下の記事に書いています。 (2)使い方と画面 サービス一覧(検索機能) 「作り方や構成を見てみたい!」という方は、カテゴリーやサービスの開発状態に合わせて、サービスを探すことができます。 カテゴリー別の検索 並び替え機能(日付、お気に入り数、コメント数) 開発中か完成済みかで表示を分ける サービス作成(登録・編集機能) 「実際にサービスを作ってみたい!」もしくは、「サービスを作った!」という人は以下のようなサービス情報を登録することができます。(いつでも、編集可能なので埋められるところだけを埋めて、開発を進めながら徐々に埋めていくことをお勧めします。) サービス名、概要、カテゴリー 使用技術・要件定義 ページごとの機能 URI設計 以上のサービスを開発する上で必要な情報を閲覧・作成・編集することができます。 サービス情報、概要 サービス名、概要、Githubページ、サービスページへのリンクが表示されます。 カテゴリーやサービスの開発状態(開発中か完成か)も表示しています。 使用技術・要件定義(機能) 使用技術を分野ごとに分けて表示します。 要件定義として機能とその説明を表示します。 ページと機能 各ページごとにどんな機能があるのかを表示します。 各ページがどんな役割を担っているのかを知ることができます。 URI設計 URI、メソッド、説明を表示します。 どんなエンドポイントにして、メソッドにしているのかとそれぞれの役割を説明しています。 タスク管理・コメント タスクを段階に分けて管理することができます。 コメントを項目(質問・感想・アドバイス)に分けて投稿することができます。 新規作成画面 新規作成画面はこんな感じ。ヒントを出してどんなことを書けばいいか教えてくれます。 マイページ 自分が開発したサービスやお気に入りしたサービスを見ることができます。 プロフィール編集画面 (3)機能一覧 メイン機能 サービス登録/編集/削除機能 お気に入り登録機能 コメント機能 並び替え機能(日付、お気に入り数、コメント数) フィルター機能(開発中 or 完成) 保存・削除時の通知機能 認証機能 ユーザー登録・ログイン・ログアウト Google、Githubアカウントを使ったソーシャルログイン機能 ゲストログイン機能 パスワード再設定機能 プロフィール編集機能 アカウント削除機能 通知機能 サービスの作成・編集などの保存を無事に完了すると通知が表示されます。 サーバー側でバリデーションなどのエラーが発生した場合の表示です。 GoogleもしくはGitHubアカウントでもログインが可能です。 パスワードを忘れた場合はパスワード再設定のリンクがSendGridで送られます。 ゲストログインも可能です。 レスポンシブ対応 どの画面でも対応しています。 2. どうやって作ったの?【技術】 どうやって作ったか気になる方は読んでみてください。 (1)使用技術 (2)ER図 (3)苦労したこと【改善点】 (1)使用技術 フロントエンド Vue.js 3.0.5 vue-scrollto 2.20.0 (コメントへのスクロール移動をするために使用) Tailwind CSS 2.0.1 @tailwindcss/line-clamp 0.2.1(文字数を制限して省略表示するために使用) ESlint 7.30.0(コード整形) Prettier 2.3.2(コード整形) フロントをVueにしたのはLaravelでJetStreamとInertiaJSで開発する場合に、デフォルトで作られるのがVue.jsだったからです。個人的にはReactの方が好きなんですが、Vueも学んでみたかったので使ってみました。TailwindCSSは記事もしてみたので、気になる方は読んでみて下さい。 バックエンド PHP 8.0 Laravel 8.40 Jetstream 2.3 (ログイン、セッション管理をするために使用) Sanctum 2.6 (CSRF対策のため) Socialite 5.2 (Google,Githubでのログインをするために使用) s-ichikawa/laravel-sendgrid-driver (メールをsendgridで送信するために使用) InertiaJS 0.4.2 (APIを作成せずにLaravelアプリと同じように作成し開発効率を上げるために使用) MySQL (Heroku ClearDB) Inertia JSって何やねん!!って方がいると思いますが、LaravelのテンプレートエンジンにBladeってありますよね、あれをVue.jsにする感じです。SPAを作る際に使われていて内部的にはaxiosとかを使っているんですが、簡単に言うとバックエンドとフロントをいい感じにつなげてくれるやつです。詳しく知りたい方のために公式サイトと分かりやすく説明されている記事があったので貼っておきます。 公式サイト https://inertiajs.com/ インフラ Heroku AWS(S3) 本当は全部AWSでやってみたかったんですが如何せん、初めてだったのでherokuでやりました。次回は、AWSで全部デプロイやってみたいですね!!ちなみに、S3はプロフィール写真を保存するためだけに使っています(笑) 本当はER図とかインフラ図とかも貼って投稿できるようにしたかったんですが、今の段階では優先度が低くなったので、時間があるときに追加してみようと思います。 その他 Git 2.33.0 XAMPP VsCode Dockerを使いたかったんですが如何せん、PCが大学生協で配られているもので容量が少なすぎて、Dockerを動かすと遅すぎて、フロントをいじっているだけで大したことしていないのにコンパイルするのに2~3分かかってしまっていたので、XAMPPに切り替えました。 本当に余談ですが、最近GitHubの使い方を勉強しています。正直作る前はとりあえず、リモートレポジトリ作ってpushしとけばいいやと思っていましたが、issue立てたりPR送ったり、branch切ったりコミットメッセージのフォーマット統一したり、いろいろエンジニアになるために必須なことを軽んじていました(-_-;) (2)ER図 サービス作りながら、あれも欲しい・これも欲しいみたいな感じになって当初予定していたものよりもテーブル数が結構増えました。ちなみに、このER図はLucidChartというサービスを使って書いています。個人的には使いやすかったです。使ってみたい人は以下のリンクからどうぞ。 テーブルの説明 テーブル名 説明 users ユーザー情報の管理(メアド、SNS、紹介文など) services サービス情報(開発者、サービス名、概要など) service_tag どのサービスにどのタグが結びついているのか tags サービスのカテゴリーを管理 tech_fields 使用技術の分野を管理 teches 技術の情報管理(技術名とバージョン) requirements 要件・機能の管理 requirement_page どのページにどの機能が結びついているのか pages ページ名の管理 uris URI設計の情報を管理 tasks タスク情報の管理 comments コメント情報の管理 sessions セッション情報の管理 password_resets パスワード再設定のメールとトークン管理 (3)苦労したこと【改善点】 フロントエンドについて Vue.jsの基本的な書き方を勉強する暇もなく書き始めていたので、調べて出てきた記事のバージョンごとの違いなどに気づくことができずにぐちゃぐちゃコードが出来上がってしまいました・・・。最終的にはVue3 の Composition APIを使って統一させました。 Vue.jsのライフサイクルやreactiveなにそれ?という感じになって、どのタイミングでstateを変更させて、どのコンポーネントでstateを管理するべきなのかが分かっていなかった。ここら辺は、コードを書く前にどんな処理の流れにするかを考える時に知っていないと難しく、Vueの設計とか思想とかを学んでいないと難しいように感じました。 tailwind CSSのカスタム性が高すぎてコードが冗長化してしまう。自分で一つ一つをしていできるからこそ、ちゃんとコンポーネントにして使い回さないと、簡単なWebアプリケーションでも余裕で1000行を超えるファイルが出来上がってしまい、その後のリファクタリングに苦労しました・・・。 教訓・・・正しい書き方、処理の流れを理解する → コンポーネントに分けて細かく設計 → 修正。このサイクルをちゃんと作ること。 バックエンドについて バックエンドの操作が基本的に初めてすぎて基本的なことが分かるまでに時間がかかりました。特にリレーション関係やModelのappendとかを自在に使えるようになるまでは少し時間がかかるなと思いました。基本的にはいろんなメソッドを全て試してみてdd()にぶち込んで見ると分かりやすいですね。調べてとりあえず手を動かしてそれから考えるのがおススメです。 テーブル設計の最適解が分かりにくいことです。サービスの設計にも関わってくると思うのですが(どのタイミングでデータをどんな頻度で取得する必要があるかなど)、これは開発を進めながらじゃないのと分からないことばかりでした。なので、一対多なのか多対多なのかとか迷っているならとりあえず簡単にできる方で試してみて動かしてみて、必要に応じて都度変更していくことが大切そうです。 ダミーデータに関してはFactory、Seederを使いながらやっていたんですが、若干ドキュメントが少ないなと感じました。リレーションのリレーションはどうするのとか、少し複雑なことをやると上手くいかず、内部的にどんな処理が行われているのかを理解するのには時間がかかりました。 一番大変だったのはInertiaJSですね。これはフロントともバックエンドともかかわっているのですが、corsのエラーの解決はとても大変でした。InertiaJSがどんな処理をしているのか、corsはどんな時に発生してどのような設定や処理を行えばエラーが出ないのかは情報が少なすぎて丸3日ぐらいはかかりました。(時間ができたら記事にします。) この方たちの記事は非常に参考になりました。SPAを作る上でCorsのエラーはよく出てくるみたいなので、少し知っておくと便利かもですね。 教訓・・・分からなくても手を動かしてデータを見てみる。焦らずに、一つ一つ理解していくことが大切。 コーディングに関して(反省) 細かく分けて設計するのではなく思い付きと勢いで1000行以上のコードや分かりにく名前の関数や変数が多数存在するカオスな状態になっていました。改めて「リーダブルコード」を実践しないと意味がないなと思いました。これは、自分の内心的にも焦っていて常に「早く完成させないと!!」みたいなものを抱えたままやっていてコードにもそれが現れてしまう形になってしまいました。結果的に、リファクタリングやファイル構成などの修正に時間取られたり、処理を根本から設計しなおすことにもなりかねないので、小さく役割を分けてフロントならコンポーネントごと、バックエンドなら一機能、一処理ごとに設計していくべきだと感じました。 やらないこと、非機能要件をちゃんとつくっておくこと。これがなかったせいで、思いつきや発想があるとすぐにテーブル変更してフロント作ってバックの処理も追加して・・・。という風に、どんどんコードが肥大化していき、何をしたいサービスなのかが自分でも分からなくなる時がありました。やるべきことと、やりたいこと、やらなくていいことをしっかりと分けて、最低限必要なサービスを作って公開してその都度変更を加えていく、言われていても分かりませんでしたが、今回の経験を通して痛いほど分かりました。 教訓・・・「Start Small Scale Fast」小さく作って早く拡大(開発→フィードバック→修正のサイクルを早くする)。これをモットーに開発していくこと。 3. どうやって勉強したの? (1)学習期間について (2)開発の日々 (3)開発中に役に立ったサイト一覧 (1)学習期間について 学習期間(2週間) PHPは、簡単な掲示板を作成しながら学びました。学習期間は1週間ほどです。基本的な文法に関しては知っていたのでPHP流の書き方を覚えるだけだったので簡単でした。 Laravelは、簡単なメモアプリをYoutubeを見ながら作成しながら学びました。どんなファイル構成で、ファイルごとの役割や基本的な書き方のみを学ぶという感じでした。学習期間は1週間ほどです。 Vue.jsは、完全に作りながら学びました。本当なら、簡単にチュートリアルくらいやっておけばよかったと思っています。(ReactでTodoアプリ作ったりしていたのでVueもそんな変わらんやろと思ってました・・・) 作成期間(2ヵ月ちょい) レポジトリのコミット数の推移です。 レポジトリを作成したのが7月15日で、その後、Laravelの学習や要件定義などをしながらテスト期間を経て、バックエンド、ダミーデータなどの作成を行います。 その後、9月に入ってから本格的にフロントエンドの開発に進みます。 最後の二週間はインフラ系の問題が発生したため、コミット数が増加しています。 以下はコードの行数の変化です。緑が増加、赤が減少です。 9月の地獄のリファクタリングの日々が現れていますね(笑)。 普通はもっと、最初が赤が少なくて緑が多くなり、最後らへんに赤が多くなると思います(笑)。 こんな感じで約3ヵ月ほどで、サービス全体が出来上がりました!! ※ちなみに、駆け出しエンジニアの方向けに書いておくと上記の二つの画像はGitHubのInsightsで見れるので他のポートフォリオを作っている方のレポジトリに行って見比べてみると、けっこう楽しいですよ(笑) (2)開発の日々 基本的に開発するのは昼から夜にかけてがほとんどでした。 自分は夜型なので夜中まで調べ物をしたりしていました。(エラーをその日の内に解決しないと安心して眠れない・・・) 作業中はBGMを流しながら始めて、その内集中しだしたら音楽が1,2時間くらいで止まるので、音楽が止まっていることに気づいたら休憩するという感じでした。 実際にコードを書く時間は調べる時間と比べて、バックエンドは3:7、フロントは5:5くらいかなって感じがしています。 一日、最低限5,6時間くらいは平均してもやっていたと思います。 やる気が無くなったら、いろんなエンジニアの方の話をYoutubeで探したり、NewsPicks見たりしながら、他の刺激を受けたりしながらモチベを保っていました。 (3)開発中に役に立ったサイト一覧 1. フロントエンド Vue 公式ドキュメント composition APIについて学べます。 v-for内のv-modelでinputタグを管理すると連動したりするので気をつけましょう。 これは、Vue触ってる人なら一度は詰まることだと思います。v-modelで値が反映されない原因は大体これをちゃんと理解できていないからだった。 Tailwind CSS 公式ドキュメント tailwind CSS のコミュニティサイト。(いろんな人のコンポーネントをコピペできる。) tailwind CSSに関するいろんな便利情報が載ってます。 Inertia JS 公式ドキュメント Inertia JSとは何かが分かる。 仕組みや動き、基本的な機能を大体使ってくれているので分かりやすいです。 2. バックエンド Laravel ドキュメント(日本語版) 簡単なWebアプリを作りながら学べます。 英語圏のサービスですが、コミュニティの質問とかも活発だし内容はすごくいいし、ハンズオンでできるので、英語で学ぶことに抵抗ない方はめちゃおススメです。 3. 全般 公式ドキュメントを読む!エラーメッセージをちゃんと読む! ライブラリ関連の問題なら、GitHubのレポジトリでissueを立てられていることがほとんどでした! Qiita、Zenn、Googleで日本の方の記事を探す。(投稿日が一年以内に絞る) エラー系はteratailに多い気がします。 以上で無理なら英語圏に頼りましょう。 さいごに 今回の経験を通して、いろいろこうやればよかったとかの後悔や改善点を見つけることができました。でも、だからこそ、今の自分がエンジニア業界の中でどんな位置にいて、これからどんなことが必要なのかが分かった気がします。なので、素直にここまでやり続けた自分を認めてあげつつ、更にエンジニアとして成長のステップを踏んでいけたらなと思います。 また、後悔している点、他の駆け出しエンジニアなどの方には経験してほしくないことがたくさんあるので、それらも記事にしていこうと思っています。 自分はこれから具体的に就職活動を始めるところですが、最近自分が思うことは環境は自分で作り上げていくものであり、人から与えられることを当たり前だと考えてはいけないということです。この一つのWebアプリケーションを作るのも、多くのエンジニアがフレームワークやライブラリを作ってWeb、インターネット、RESTなどの基礎的な考え方から設計・開発してくださった人がいるからこそだと感じました。コードを書いていると、ふと、そういう方たちと繋がるような感じがします。時代も場所も超えて、そういう思いが伝わることができるのがエンジニアの特権だと思っています。 これからも、まだまだ与えられるや教えていただくことが多いと思いますが、自分が学んだこと・自分が与えられることに関しては少しずつ自分も誰かのために発信したりしていけたらと感じました。 最後に僕が好きな本の一節を残しておきます。 「世界がどうなるか」を心配する時間があるなら、「世界をどうするか」を考えたい By 佐渡島庸平 「僕らの仮説が世界を作る」より エンジニアとして世界を作る側に回っていきたいですね! 最後までお読みいただき、ありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】LaravelでYoutubeのお気に入りCuration(まとめ)アプリを作る【第4回: ログイン&動画登録】

(この記事は作成中です。) こんにちは。 ITエンジニアの濱辺(ハマベ)です。 今回は、ログイン&お気に入り動画登録機能を実装していきます。 ↓第3回はこちら LaravelでYoutubeのお気に入りCuration(まとめ)アプリを作る【第3回】 ↓こちらの画面定義書のものを作っていきます。 Youtube-Curation 画面定義所 (googleスプレッドシート) ログイン機能の実装 ログイン機能についても、Laravelに標準で備わっているファイルがあります。 基本機能は最初から用意されているんですね。 Route設定 下記3つのrouteを記述しましょう。 web.php Route::get('login', 'Auth\LoginController@showLoginForm')->name('login'); Route::post('login', 'Auth\LoginController@login')->name('login.post'); Route::get('logout', 'Auth\LoginController@logout')->name('logout'); それぞれ、 - ログインページ表示 - ログインフォーム情報の送信 - ログアウト処理 のためのrouteです。 LoginController確認 Controllers/Auth/LoginControllerを開いてみましょう。 LoginController.php <?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { //(中略) use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = RouteServiceProvider::HOME; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest')->except('logout'); } } ログアウト以外のアクションは、guest(非ログイン)ユーザしか実行できない、といったことが記述されています。 上記記述のうち、推移先のページ情報だけ書き換えましょう。 LoginController.php protected $redirectTo = RouteServiceProvider::HOME; ↓ //変更 protected $redirectTo = '/'; ログインページの見た目実装 ログインページのviewを作成します。 view/auth/login.blade.phpを作成しましょう。 login.blade.php @extends('layouts.app') @section('content') <div class="center jumbotron bg-warning"> <div class="text-center text-white"> <h1>YouTubeまとめ × SNS</h1> </div> </div> <div class="text-center"> <h3 class="login_title text-left d-inline-block mt-5">ログイン</h3> </div> <div class="row mt-5 mb-5"> <div class="col-sm-6 offset-sm-3"> {!! Form::open(['route' => 'login.post']) !!} <div class="form-group"> {!! Form::label('email', 'メールアドレス') !!} {!! Form::email('email', old('email'), ['class' => 'form-control']) !!} </div> <div class="form-group"> {!! Form::label('password', 'パスワード') !!} {!! Form::password('password', ['class' => 'form-control']) !!} </div> {!! Form::submit('ログイン', ['class' => 'btn btn btn-primary mt-2']) !!} {!! Form::close() !!} <p class="mt-3">{!! link_to_route('signup', '新規ユーザ登録する?') !!}</p> </div> </div> @endsection これでログインができるようになりました。 ヘッダーからログインページへ推移できるようにする ヘッダーを書き換えて、ログイン状態と非ログイン状態で表示分けできるようにしましょう。 header.blade.php <header class="mb-5"> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand" href="/">YouTube-Curation</a> <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#nav-bar"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="nav-bar"> <ul class="navbar-nav mr-auto"></ul> <ul class="navbar-nav"> @if (Auth::check()) <li class="nav-item">{!! link_to_route('logout', 'ログアウト', [], ['class' => 'nav-link']) !!}</li> <li class="nav-item"><a href="" class="nav-link">マイページ</a></li> @else <li class="nav-item">{!! link_to_route('signup', '新規ユーザ登録', [], ['class' => 'nav-link']) !!}</li> <li class="nav-item">{!! link_to_route('login', 'ログイン', [], ['class' => 'nav-link']) !!}</li> @endif </ul> </div> </nav> </header> @if (Auth::check())から、@elseまでの間がログイン状態での表示。 @elseから@endifの間が非ログイン状態の表示を表しています。 Auth::check()は「ユーザがログイン状態か?」を判断する関数です。 トップページにログインユーザ名を表示 トップページにログインしたユーザの名前を表示させましょう。 welcome.blade.php(一部抜粋) @extends('layouts.app') @section('content') <div class="center jumbotron bg-warning"> <div class="text-center text-white"> <h1>YouTubeまとめ × SNS</h1> </div> </div> <div class="text-right"> @if(Auth::check()) {{ Auth::user()->name }} @endif </div> @endsection さて、一通り実装できたので、ログイン・ログアウトを実行してみましょう。 ログイン画面 ログインした状態 ログアウト実行後(非ログイン状態) 無事に動作したでしょうか。 できましたら、動画登録機能の実装をしていきましょう! 動画登録の実装 まずは、movie用のmysqlテーブルを作成していきます。 Moviesテーブルを作成 まず、Moviesテーブルを作成します。 下記のコマンドを実行しましょう。 # php artisan make:migration create_movies_table --create=movies ファイルが作成されるので、中身up()の中身を書き換えましょう。 [作成日時]_create_movies_table.php(一部抜粋) public function up() { Schema::create('movies', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned()->index(); $table->string('url'); $table->string('comment')->nullable(); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); } 5つのカラムを作るように記述しました。 id:各動画に付ける連番 user_id:動画を登録したユーザのID url: YouTube動画のURL comment: 動画に対するコメント (nullable = nullでも投稿できる) timestamps:動画登録日時・動画更新日時 $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');は、紐づいているユーザIDを持つユーザが消去されたら、moviesテーブルの該当カラムも一緒に削除する、といった意味になります。 マイグレートを実行してみましょう。 # php artisan migrate すると、下記のエラーが発生するかと思います。 PDOException::("SQLSTATE[HY000]: General error: 3780 Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'movies_user_id_foreign' are incompatible.") これは、usersテーブルのidと、moviesテーブルのidの型が異なることが原因で発生しています。 下記の部分を修正しましょう。 2014_10_12_000000_create_users_table.php Schema::create('users', function (Blueprint $table) { $table->increments('id'); 〜略 }); moviesモデルの作成 以下のコマンドにて、Movie モデルを作成しましょう。 # php artisan make:model Movie 生成されたMovie.phpに以下のように記述し、(’user_id’,’url’,’comment’)を登録できるようにしましょう。 Movie.php <?php namespace App; use Illuminate\Database\Eloquent\Model; class Movie extends Model { protected $fillable = ['user_id','url','comment'];    //多対一の関係 public function user() { return $this->belongsTo(User::class); } } Userモデルに、Movieモデルとの関係を記述しましょう。(一対多、一人のuserに複数のmovieの関係) User.php ~ 省略 ~ /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ];    //追加(movieとの一対多の関係) public function movies() { return $this->hasMany(Movie::class); } } ここまで出来たら、一度tinkerを使って動画の登録を試してみましょう。 >>> use App\User >>> $user = User::find(1) => App\User {#4104 id: 1, name: "sample1", email: "sample1@sample.com", email_verified_at: null, #password: "$2y$10$vHoB.o8.Gd.KGmkflb06MOVuRTnEU9KihfJ9himiOxjNCDaZ7d4oS", #remember_token: null, created_at: null, updated_at: null, }>>> use App\Movie >>> $user->movies()->get(); => Illuminate\Database\Eloquent\Collection {#xxx all: [], } >>> $user->movies()->create([ ... 'url' => 'Gn61Vq9v6GY', ... 'comment' => 'sample movie 1']) => App\Movie {#3324 url: "Gn61Vq9v6GY", comment: "sample movie 1", user_id: 1, updated_at: "2021-10-12 07:51:46", created_at: "2021-10-12 07:51:46", id: 1, } >>> $user->movies => Illuminate\Database\Eloquent\Collection {#4252 all: [ App\Movie {#4249 id: 1, user_id: 1, url: "Gn61Vq9v6GY", comment: "sample movie 1", created_at: "2021-10-12 07:51:46", updated_at: "2021-10-12 07:51:46", }, ], } MovieのRouter作成 Movie関連のRouterを記述していきます。 今回はresorceを使用します。resourceは、主要7つのrouteを自動作成してくれます。 web.phpを下記のようにしましょう。 web.php Route::get('/', 'UsersController@index'); //書き換え Route::get('signup', 'Auth\RegisterController@showRegistrationForm')->name('signup'); Route::post('signup', 'Auth\RegisterController@register')->name('signup.post'); Route::get('login', 'Auth\LoginController@showLoginForm')->name('login'); Route::post('login', 'Auth\LoginController@login')->name('login.post'); Route::get('logout', 'Auth\LoginController@logout')->name('logout'); // 追記分 Route::resource('users', 'UsersController', ['only' => ['show']]); //ログイン認証を通ったユーザのみ、アクセスできるroute Route::group(['middleware' => 'auth'], function () { Route::resource('movies', 'MoviesController', ['only' => ['create', 'store', 'destroy']]); }); UsersController作成 UserControllerを作成し、トップページを表示するindexアクションを記述していきます。 # php artisan make:controller UsersController app/Http/Controllers/UsersController.phpが作成される UsersController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\User; //追記 class UsersController extends Controller { public function index() { $users = User::orderBy('id','desc')->paginate(9); return view('welcome', [ 'users' => $users, ]); } } 'users' => $users,は、usersという変数をviewに持っていく、という処理を表しています。 Viewの作成 Movies の一覧を表示する共通の View として、 users.blade.php を作成します。 usersフォルダを作成し、ファイルを作っていきましょう。 resources/views/users/users.blade.php users.blade.php <h2 class="mt-5 mb-5">users</h2> <div class="movies row mt-5 text-center"> @foreach ($users as $key => $user) @php $movie=$user->movies->last(); @endphp @if($loop->iteration % 3 == 1 && $loop->iteration != 1) </div> <div class="row text-center mt-3"> @endif <div class="col-lg-4 mb-5"> <div class="movie text-left d-inline-block"> @{{ $user->name }} <div> @if($movie) <iframe width="290" height="163.125" src="{{ 'https://www.youtube.com/embed/'.$movie->url }}?controls=1&loop=1&playlist={{ $movie->url }}" frameborder="0"></iframe> @else <iframe width="290" height="163.125" src="https://www.youtube.com/embed/" frameborder="0"></iframe> @endif </div> <p> @if(isset($movie->comment)) {{ $movie->comment }} @endif </p> </div> </div> @endforeach </div> {{ $users->links('pagination::bootstrap-4') }} ここで少し、見た目を整えるためにCSSを適用しましょう。 下記のようにlinkを、app.blade.phpに追記します。 app.blade.php <head> <meta charset="utf-8"> <title>YouTubeまとめ×SNS</title> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">      //追加 <link rel="stylesheet" href="{{ asset('/css/styles.css') }}"> </head> 続いて、public/css/styles.cssを作成し、下記を記述します。 styles.css .movie{ width: 290px; } .movie > p{ height: 72px; } .button{ width: 290px; } これで、下記のような見た目となるはずです。 それぞれ、ユーザに登録した最新の動画のサムネが表示され、クリックすると、再生できるはずです。 ここまでで、「動画を保存できる」ようにはなりました。 次はwebページから動画を登録できるようにしていきます。 MoviesController作成 まずは、下記のコマンドでMoviesControllerを作成しましょう。 # php artisan make:controller MoviesController app/Http/Controllers/MoviesController.phpが作成されるので、 createアクションを記述していきましょう。 createアクション作成 MoviesController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\User; use App\Movie; class MoviesController extends Controller { public function create() { $user = \Auth::user(); $movies = $user->movies()->orderBy('id', 'desc')->paginate(9); $data=[ 'user' => $user, 'movies' => $movies, ]; return view('movies.create', $data); } } 今回は、$dataという変数に、$userと$moviesを配列として渡して、$dataをViewに渡すようにしています。 Viewの作成 まず、headerから動画の新規登録ページへ飛べるようにしましょう。 header.blade.php @if (Auth::check()) <li class="nav-item">{!! link_to_route('logout', 'ログアウト', [], ['class' => 'nav-link']) !!}</li> <li class="nav-item"><a href="" class="nav-link">マイページ</a></li> <li class="nav-item">{!! link_to_route('movies.create','動画を登録する',['id'=>Auth::id()],['class'=>'nav-link']) !!}</li> <!--↑追記--> @else 次に、動画登録フォームを作成しましょう。 resources/views/movies/create.blade.phpを新規作成します。 create.blade.php @extends('layouts.app') @section('content') <div class="text-right"> {{ Auth::user()->name }} </div> <h2 class="mt-5">動画を登録する</h2> {!! Form::open(['route'=>'movies.store']) !!} <div class="form-group mt-5"> {!! Form::label('url','新規登録YouTube動画 "ID" を入力する',['class'=>'text-success']) !!} <br>例)登録したいYouTube動画のURLが <span>https://www.youtube.com/watch?v=-bNMq1Nxn5o なら</span> <div>  "v="の直後にある "<span class="text-success">-bNMq1Nxn5o</span>" を入力</div> {!! Form::text('url',null,['class'=>'form-control']) !!} {!! Form::label('comment','登録動画へのコメント',['class'=> 'mt-3']) !!} {!! Form::text('comment',null,['class'=>'form-control']) !!} {!! Form::submit('新規登録する?',['class'=> 'button btn btn-primary mt-5 mb-5']) !!} </div> {!! Form::close() !!} <h2 class="mt-5">あなたの登録済み動画</h2> @include('movies.movies', ['movies' => $movies]) @endsection 下記の部分に注目してください。 <h2 class="mt-5">あなたの登録済み動画</h2> @include('movies.movies', ['movies' => $movies]) これは、moviesフォルダのmovies.blade.phpを読み込む記述です。 こうして別ファイルに分けた方が、後々の変更に強くなるのです。 というわけで、movies/movies.blade.phpを作成しましょう。 movies.blade.php <div class="movies row mt-5 text-center"> @foreach ($movies as $key => $movie) @if($loop->iteration % 3 == 1 && $loop->iteration != 1) </div> <div class="row text-center mt-3"> @endif <div class="col-lg-4 mb-5"> <div class="movie text-left d-inline-block"> <div> @if($movie) <iframe width="290" height="163.125" src="{{ 'https://www.youtube.com/embed/'.$movie->url }}?controls=1&loop=1&playlist={{ $movie->url }}" frameborder="0"></iframe> @else <iframe width="290" height="163.125" src="https://www.youtube.com/embed/" frameborder="0"></iframe> @endif </div> <p> @if(isset($movie->comment)) {{ $movie->comment }} @endif </p> </div> </div> @endforeach </div> {{ $movies->links('pagination::bootstrap-4') }} これで、ヘッダーの「動画を登録する」から遷移した画面がこうなるはずです。 MoviesContoroller storeアクション作成
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MVCについてとブラウザからのリクエスト→サーバーへのレスポンスまでの流れ

MVCについて webでは、ブラウザ(Safari,Chomeなど)とサーバーの間で ブラウザ→サーバへのリクエストと、それに対しての サーバー→ブラウザへのレスポンスのやりとりが行われています。 その内部ではMVCが大きな役割を果たしています。 MVCとは ソフトウェアの設計モデルの一つで、機能をモデル・ビュー・コントローラーの3つの役割に分けて実装するという方法のことです。 モデル・ビュー・コントローラーとは? ではモデル・ビュー・コントローラーとはどのような役割を果たすものなのでしょうか? それぞれの役割について説明します。 モデル コントローラーとデータベースとのやりとりを介している。ビジネスロジックの実装に関わっています。 ビュー DBから取得したデータなどを元にHTMLを作成する。ブラウザへの反映に大きく関与する。 コントローラー モデルの内容についての指揮をおこうなう。この中に実行したいアクションの内容が含まれている。 また、コントローラーの部分が肥大化してしまう傾向がある ブラウザからのリクエストからサーバーへのレスポンスまでの流れ では実際にブラウザからリクエスト→サーバーへのレスポンス、その情報がブラウザに表示されるまでの流れについて説明して行きたいと思います。 ①URIとしてリクエストを送る 例えばAmazonのログインを行いたいとします その場合、 ②初期処理 ここではLaravelやRailsなどのフレームワークで必要な機能の読み込みが行われます。 ③URLからのルーティング リクエストされたURIの情報をもとにルーティングを行います。 ルーティングとはどのコントローラからどのアクションを実行すればいいの?を判断すること。 このURIの中にはポート番号や、プロトコル(ネットワークの規約のようなもの)、ドメイン名の情報が含まれています。 ④コントローラとモデル、データベースのやりとり コントローラーには様々なアクションがあり、ルーティングにより特定のアクションが呼び出されます。コントローラーは呼び出されたアクションを元にモデルを介してデータベースとのやりとりを行います。具体的にはデータの保存や取得を行なったりします。 ⑤ビューに取得したデータを渡す コントローラーは取得したデータをビューに渡し、そのデータを元にビューはHTMLの生成を行います ⑥コントローラーに作成したHTMLの情報を渡す ビューはコントローラーに作成したHTMLの情報を渡します。 ⑦HTMLの情報をブラウザに返す コントローラーはそのHTMLの情報をブラウザに返します。 ⑧ブラウザに表示 このようにしてリクエストされたURIのデータはブラウザに表示されます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む