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

【Laravel8】Eloquentのupsert()について

Eloquentのupsert()って? これです https://readouble.com/laravel/8.x/ja/eloquent.html#upserts Flight::upsert([ ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99], ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150] ], ['departure', 'destination'], ['price']); 同じEloquentでupsertするメソッドだとupdateOrCreate()とかありますね。 比較的最近(8.10以降?)実装されたものらしく、またドキュメント読んだだけではイマイチ使い方がわからなかったので、自分で検証したことも含め備忘録がてら書き残しておこうと思います。 upsert()についてもですが、Laravel自体始めて日が浅いため何か間違ってる箇所があればご指摘をお願いします。 環境 PHP:7.4 Laravel:8.13.0 解説 基本 $data = [ ['id' => 1,'departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99], ['id' => 2,'departure' => 'Chicago', 'destination' => 'New York', 'price' => 150] ] Flight::upsert($data, ['id'], ['price']); ドキュメントの例に少し手を加えたものです。 第一引数に更新したい内容、第二引数にプライマリーキー、第三引数に更新したいカラムをそれぞれ配列で渡します。第二引数はSQLServer以外必須だそうです。 個人的にドキュメント読んでわかりにくいと思ったのが第二引数に指定したカラムを第一引数の配列に含めるかどうか。 結論から言うと含めます。ないと確定でInsertになってしまいます。 例ではidカラムをプライマリーキーとして想定しているので第二引数に['id']と書いていますが、第一引数の$dataという配列にもidカラムの値を入れています。 第二引数でプライマリーキーさえ指定すれば第一引数の配列に含めなくてもいい感じにInsertかUpdateか判断してくれるのかと思ったのですが、そんなに甘くはありませんでした。 ただこの仕様、複合主キーテーブルに対してUpsertするときすごく便利です。 イマドキ複合主キー?と思われそうですが、仕事で複合主キーのテーブルを取り扱う機会がすごく多いのでupsert()は救世主でした。 (今まではクエリビルダー使ったり自前でメソッド作ったりしてました) 第三引数について 第三引数にはupdate時更新したいカラムを配列で指定します。先ほどの例だとpriceカラムのみ更新します。 未指定の場合は第一引数で指定したすべてのデータを更新するようです。Modelのguardedで更新しないカラムを指定していれば除外してくれるのかな?(未確認) ただし 空の配列を指定した場合は更新日時カラム(updated_at)のみ更新します。 なので第一引数にいくら値を指定しても更新されません。 $data = [ ['id' => 1,'departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99], ['id' => 2,'departure' => 'Chicago', 'destination' => 'New York', 'price' => 150] ] //$dataに含まれるModelのguardedで指定したカラム以外を更新 Flight::upsert($data, ['id']); //updated_atのみ更新。$dataで指定したdepartureやpriceは更新されない Flight::upsert($data, ['id'],[]); 参考 https://readouble.com/laravel/8.x/ja/eloquent.html#upserts https://stackoverflow.com/questions/66198271/laravel-8-eloquent-upsert-inserting-new-records
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelからVueにのデータ渡す

ネット上の情報を収集してから、実装した上での心得を整理してみました。 背景 Bladeファイルでは、Laravel Controllerからのデータを受け取って使うことが可能ですが、Vue.jsファイルの中に同じことができるかどうかを知りたくて、調査してみました。 調査した結果だと現時点では同じことができなさそうですが、代案がありまして、これを実装すればControllerからViewに渡すデータをVue側で取れます。 jsの処理をBladeファイル内に実装すれば良いではないか? そういうのも考えましたが、これも代案の一つ選択肢だと思います。 けど、やはりjs処理をBladeファイルに書きたくないので、別の案をしました。 対応方法 簡単な方法ですので、先に内容を書いておきます。 Bladeファイル内Controllerから渡してきたデータを受け取って、jsのGlobal変数に保存するとVue側で利用することが可能になります。 これからは対応の詳細を書きます。 1. 全体の構成 2. 本題に入る 全体の構成 Controllers app/Controllers/xxxController.php 表示したいViewと渡したいデータを設定します。 xxxController.php ...略 public function index() { ...略 return view('life_style/life_style')->with('data', $data); } Views resources/views/yyy.blade.php Viewの構成を管理します。 また、laravel-mixを使ってVue関連処理のjsファイルをrequireしますので、Vue関連処理のjsファイル(resources/js/zzz.js)が必要となります。また、resources/js/zzz.jsにはresources/bootstrap.jsをrequireしています。 yyy.blade.php ...略 <script src="{{ mix('js/life_style.js') }}"></script> zzz.js require('../bootstrap'); ...略 laravel-mixを使うため、webpack.mix.jsも編集します。 webpack.mix.js mix .js('resources/js/zzz.js', 'public/js') .vue(); Routes ルートを設定するため、routes/web.phpを編集します。 web.php ...略 Route::get('/xxx_index', [xxxController::class, 'index'])->name('xxx.index'); ここまでのまとめ 一つの画面を作成するには、追加&修正が必要なファイルは下記となります。 - xxxController.php - yyy.blade.php - zzz.js - webpack.min.js - web.php 本題に入る Vue側でControllerのデータを使う 対応方法にも書きましたが、まずはBladeファイル側でControllerのデータを受け取る。受け取ったデータをwindow.LaravelというGlobal変数に保存します。 同じ処理を各Bladeファイルに実装するのではなく、共通化できるようにしたいため、親Bladeファイル(base.blade.php)を作成し、その中に処理を実装し、各Bladeファイルがこの親Bladeファイルに継承するようにしました。 下記のように、<script>内にjsの処理を実装しました。 base.blade.php ...略 <script> window.Laravel = {!! json_encode(['data' => $data ?? null, 'api_token' => $api_token ?? null ]) !!}; </script> Vue側で利用する let data = window.Laravel.data; これでVue側で利用することができました! 追加:api_tokenの処理 api_tokenもController側から渡してくる場合は、同じくjs側で使えます。 APIを呼び出す時に必要なデータですので、axiosに設定しておくと便利です。 (注意点としては、Blade側でControllerのデータを取得して、Global変数に設定するのをbootstrap.js実装するのより優先にしないと行けないことです。) bootstrap.js window.axios = require('axios'); if (Laravel && Laravel.api_token) { window.axios.defaults.headers .common['Authorization'] = 'Bearer '+ Laravel.api_token; }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelからVueにデータ渡す

ネット上の情報を収集してから、実装した上での心得を整理してみました。 背景 Bladeファイルでは、Laravel Controllerからのデータを受け取って使うことが可能ですが、Vue.jsファイルの中に同じことができるかどうかを知りたくて、調査してみました。 調査した結果だと現時点では同じことができなさそうですが、代案がありまして、これを実装すればControllerからViewに渡すデータをVue側で取れます。 jsの処理をBladeファイル内に実装すれば良いではないか? そういうのも考えましたが、これも代案の一つ選択肢だと思います。 けど、やはりjs処理をBladeファイルに書きたくないので、別の案をしました。 対応方法 簡単な方法ですので、先に内容を書いておきます。 Bladeファイル内Controllerから渡してきたデータを受け取って、jsのGlobal変数に保存するとVue側で利用することが可能になります。 これからは対応の詳細を書きます。 1. 全体の構成 2. 本題に入る 全体の構成 Controllers app/Controllers/xxxController.php 表示したいViewと渡したいデータを設定します。 xxxController.php ...略 public function index() { ...略 return view('/yyy')->with('data', $data); } Views resources/views/yyy.blade.php Viewの構成を管理します。 また、laravel-mixを使ってVue関連処理のjsファイルをrequireしますので、Vue関連処理のjsファイル(resources/js/zzz.js)が必要となります。また、resources/js/zzz.jsにはresources/bootstrap.jsをrequireしています。 yyy.blade.php ...略 <script src="{{ mix('js/zzz.js') }}"></script> zzz.js require('../bootstrap'); ...略 laravel-mixを使うため、webpack.mix.jsも編集します。 webpack.mix.js mix .js('resources/js/zzz.js', 'public/js') .vue(); Routes ルートを設定するため、routes/web.phpを編集します。 web.php ...略 Route::get('/xxx_index', [xxxController::class, 'index'])->name('xxx.index'); ここまでのまとめ 一つの画面を作成するには、追加&修正が必要なファイルは下記となります。 - xxxController.php - yyy.blade.php - zzz.js - webpack.min.js - web.php 本題に入る Vue側でControllerのデータを使う 対応方法にも書きましたが、まずはBladeファイル側でControllerのデータを受け取る。受け取ったデータをwindow.LaravelというGlobal変数に保存します。 同じ処理を各Bladeファイルに実装するのではなく、共通化できるようにしたいため、親Bladeファイル(base.blade.php)を作成し、その中に処理を実装し、各Bladeファイルがこの親Bladeファイルに継承するようにしました。 下記のように、<script>内にjsの処理を実装しました。 base.blade.php ...略 <script> window.Laravel = {!! json_encode(['data' => $data ?? null]) !!}; </script> Vue側で利用する let data = window.Laravel.data; これでVue側で利用することができました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelで検索条件をページネーションに反映する方法

環境 Dockerで構築したLEMP環境 ・Laravel 6.20.22 ・Nginx 1.8 ・MySQL 8.0 ・PHP 7.4.16 概要 Bladeテンプレートで以下のPaginationリンクを設置し、ページめくりをすると、検索フォームで入力した検索条件が反映されずにページがめくられてしまう。 {{$variables->links()}} 同様の事例 ・teratail >> laravelでページングの検索条件を別ページに渡って保持する方法 私と同様に検索条件がページネーションに反映されない方のご質問に対して、以下に示す結論で記載するコードに書き換えると良いという回答あり。 →助かります!!! 結論 何も考えずに、ページネーションのリンクを以下のコードに書き換えれば終了。 blade.php {{$variables->appends(request()->query())->links()}} //$variablesはご自身の値を使用ください。 意味としては、 ・appends()メソッドで配列を渡す ・request()メソッドで、ページで送信されるリクエストを取得する ・request()メソッドの中で、さらにquery()メソッドを使うことでリクエストの中のクエリストリングのみを取得できる。 ※クエリストリングとは、urlの中の?名前=○○のような?以降の値のこと。 解説は以下の記事が特に参考になりました。 ・laravelで検索結果ページネーションを有効にするカンタンな方法 ・Laravelマニュアル >> リクエストの取得 ・e-Words >> クエリストリング
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

シーサーフ(CSRF)に関して

シーサーフ(CSRF)に関して学んだこと まえがき Laravel初心者が学ぶ課程で気になったことの学習メモとしてアウトプットしています。 @csrf CSRF(Cross-site Request-Forgery)、Webアプリケーションの脆弱性の一つもしくはそれを利用した攻撃。 注意が必要なwebサイトの特徴  - Cookieを用いたセッション管理  - Basic認証  - SSLクライアント認証 ユーザがログイン状態(Cookieに情報が保持されている)ならば攻撃される可能性がある。。。 こ、こわい LaravelのcsrfはRailsでいうStrong Parameter的な役割 viewファイルに記述することで簡単に情報を保護することができる。 セキュリティトークン(ワンタイムトークン)の発行。 生成したワンタムトークンをhiddenパラメータでwebブラウザに返す <form method="POST" action="/profile"> @csrf ... </form> POSTリクエストの処理の際にCSRF対策をしなければいけない。 formとセットで記述する。 参考URL
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む