2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
Laravel クイズ (for Qiita Night) (全1記事)
リンクをコピー
記事をブックマーク
mpyw氏:「Laravelクイズ ~Qiita Night PHP 2023 Winter~」ということで始めます。よろしくお願いします。今回は「Qiita」のスライドを使わせてもらっています。(倍率が)100パーセントだと見にくかったので、50パーセントでだいぶ縮小して表示しています。自己紹介をしていると時間がないので、さっさと始めていきます。
以前の問題。最初に作ったLaravelクイズがあって、それに続き弊社の@fuwaseguくんが作ってくれた問題があって、(さらに)それに続いて第3弾ということで、今回また私から出題させてもらった内容になります。
以前から「Twitter」上、「X」上でこの問題については共有していたので、それのおさらいというか。今回初めて見る方もいると思いますが、その方向けにけっこう丁寧に説明しながら、知っている方はおさらいという感じで見てもらえれば幸いです。
じゃあ進めていきます。第1問。PUT users/
1番がプロパティアクセスでuserを取り出す。2番がget()というメソッドを使って取り出す。3番がinput()というメソッドを使って取り出す。4番がall()というメソッドを使って取り出したあと、userというキーにアクセスする。
1個だけ非常に危うい動作をするものがあります。5秒ぐらい待ちます。
ちょっと時間もないので発表にいきます。正解は1番ですね。$request->userでアクセスをすると非常に危険です。正しく内容がPOSTされた時は$request->input('user')と等価の動作を取るんですが、そのリクエストの$requestペイロードの中にuserというものが存在しない時、なんとこのコントローラーの引数にあるUser $userの値を取りにいってしまいます。
リクエストの中身かもしれないし、そのモデルそのもののオブジェクトを取ってしまうかもしれないということで、ぜんぜん違うものを取ってしまう可能性があるので、この書き方はできれば使わないようにしてほしいです。これは以前に私がQiitaで書かせてもらった記事のおさらいになります。
他のものに関して軽く説明しておくと、2番の$request->get('user')はたぶん見たことがある方はほとんどいないかと思いますが、一応Laravelでちゃんと存在しています。中身は(スライドに)書かせてもらったとおり、Symfonyのベースとなっているリクエストを継承しているだけの処理になります。
Laravelでよくある、JSON形式を解釈してドットチェインでキーを指定して中身を取り出すという動作をとることができないので、実質ちょっと使い勝手が悪い。$_POSTしかハンドリングができないので実用性はちょっと薄いかなということで、豆知識程度に覚えておいてください。
$request->input('user')に関しては説明不要ですね。もっともよく使われるものです。とりあえずこれを使っておけば困らないと思います。$request->all()に関しては同等の動きなので、特に説明はいらないかなと思います。
じゃあ次にいきます。2問目。Eloquent Modelのスコープ機能に関して、以下のうち使い方が間違っているものが1つだけあります。
1番。グローバルスコープという機能に関して、そのapply()メソッドで受けた$queryという変数にそのままWHEREとかをチェインして条件を付与していく。2番が、新しいクエリインスタンスを作り直して、それをリターンする。既存のオブジェクトを編集するというよりは新しいものをリターンするという動きですね。3番、4番がそれのローカルスコープ版になります。
次のうち、1個だけ動作として間違っているものがあります。じゃあ5秒ほど待ちます。
じゃあ正解を発表します。正解は2番です。グローバルスコープクラスに関しては、返り値がインターフェイス上でvoidと記述されているのでちょっと不便ですが、これに逆らうことはできないです。
どうしてもインスタンスごと入れ替えたいような処理があったら、ローカルスコープを使って実装してもらう必要があるということになります。
じゃあ次に3問目にいきます。これは時事問題ということで、私が最近X上で何回かつぶやいていた内容になるんですが、いきます。
Eloquent Builderの機能に関して、間違った説明をしているものはどれでしょう?
1番。createOrFirst()というメソッドは、まずINSERTしてみて、ユニークキー制約エラーになった時だけSELECTするという動きをする。2番。firstOrNew()は、まずSELECTしてみて、結果があればそれをインスタンス化、なければ空のPHPのオブジェクトでそのままモデルクラスをNEWするという動きをする。3番。firstOrCreate()は、まずSELECTしてみて、結果が見つからなかった時だけINSERTする。4番。updateOrCreate()は、まずUPDATEしてみて空振りした時だけ、要するにそのアップデートが走らなかった時だけINSERTする。
1つだけ間違っているものがあります。どれでしょうか。
発表にいきます。正解は4番です。updateOrCreate()が間違っています。updateOrCreate()は、最初にupdateという名前から始まっていますが、まずはSELECTクエリが投げられます。SELECTした結果があったら、それを基にUPDATEという処理が走って、なければINSERTされます。だから実際の動きはfirstOrCreate()みたいな名前が妥当というわけですが、省略したような名前になっていますね。
1番のcreateOrFirst()は聞き慣れない方がいるかもしれないですが、Laravel 10xで追加された機能になります。確かLaravel 10.20ぐらいだったかな? わりと最近の機能です。
これは宣伝になるんですが、createOrFirst()に加えて、firstOrCreate()とupdateOrCreate()に関しても以前は使われていなくて、シンプルにcreate()を使っていました。10.29以降は内部的にcreateOrFirst()を再利用するようになっていて、これによって、並列実行された時、例えばレプリケーション遅延とかが起こっていたとしても、安全なフォールバック動作を取ってくれるようになっています。
ということで、firstOrCreate()、updateOrCreate()の実用性が、10.29以降は以前よりも上がっていると思ってもらってかまいません。
では4問目にいきます。タスクスケジューリング機能に関して、間違った説明をしているものはどれでしょう。
1番。withoutOverlapping()とonOneServer()という機能がどっちもあるんですが、ともにタスクの重複実行を防ぐための機能である。2番。バッチサーバーが複数台構成の場合、必ずしもこれらを両方使わなければならないとは限らない。どっちかだけで十分ということですね。3番。複数台構成の場合、これらを使うためには必ずキャッシュドライバとして、ファイルじゃなくて、RedisとかMemcachedといったKVSを使用しなければならない。4番。withoutOverlapping()は単一台構成の場合に使っても意味がある。
タスクスケジューリング機能は使っていない方もいるかもしれないですが、ご了承ください。どれでしょうか。
正解は3番ですね。複数台構成の場合、これらを使うためには必ずキャッシュドライバとしてKVSを使用しなければならない。実用上、KVSを使うことがほとんどですが、これは引っかけ問題で、実はKVSを用意せずともリレーショナルデータベース、MySQLとかPostgreSQLを使ってもらってOKです。
ローカルファイルを使うと、そのインスタンス内だけでしか共有されないんですが、共有されるものを選べばなんでもいいので。KVSじゃなくてRDBでもOKという引っかけ問題ですね。
このあたりに関しては、以前のQiitaの記事で説明させてもらっています。
(スライドを示して?)このあたりは補足ですが、時間がないので端折ります。
5問目。テストで使用できるトレイトについて、間違った説明をしているものはどれ?
1番。DatabaseMigrationsはテストメソッド開始ごとに毎回全テーブルをDROPして作り直しを行う。2番。DatabaseTransactionsはテストメソッド開始ごとにトランザクションを開始し、テストメソッド終了時にロールバックを行う。3番。DatabaseTruncationはテスト全体で1回だけ、全テーブルの全行削除を行う。4番。RefreshDatabaseはテスト全体で1回だけ、テーブルのDROPと作り直しを行う。
どれでしょうか。この中でたぶん一番有名なのがRefreshDatabaseだと思いますが、それ以外にもたくさん存在しています。
では正解にいきます。間違っているものはどれでしょう。3番です。DatabaseTruncationはテストメソッド開始ごとが正解になります。DatabaseTransactionsとかRefreshDatabaseのようにテスト用トランザクションが生えないので、比較的実操作に近いテストが可能です。
ということで、個人的にはこれはRefreshDatabaseよりも今はDatabaseTransactionsを使ったほうがいいんじゃないかなというぐらいで、わりと推しているトレイトになります。
(スライドを示して)一応他の説明も書いてあります。もうあと1分しかないので飛ばしていきます。
6問目。UUIDについて間違った説明をしているものはどれでしょう。
1番。Strクラスのuuid()というメソッドはデフォルトでUUID v4を返す。2番。orderedUuid()はUUID標準に準拠していない。3番。uuid()もしくはorderedUuid()というメソッドはそれぞれ別々にロジックをカスタムすることができる。4番。orderedUuid()は、2059年問題みたいな生成スペース枯渇に関する問題を抱えている。
1つだけ間違った説明があります。
では正解にいきますかね。これが最後の問題です。3番です。uuid()、orderedUuid()のロジックをそれぞれ別にカスタムすることはできません。非常に残念な実装になっているんですが、createUuidsUsing()というメソッドで、どちらもここで設定したクロージャ―を使うような動きになってしまいます。非常に残念な実装です。なぜそうなっているかは私にもわかりません。
uuid()に関してはデフォルトのUUID v4が返ってきますね。orderedUuid()はLaravelがオレオレで用意したものであって、UUID標準は無視しています。
2059年問題があるということに関しても正しいです。なので、長期的に動作をするソフトウェアを作る場合はorderedUuid()は使わずに、整列されているUUIDで良ければUUID v7というものを自分で用意したほうがいいかなと考えています。
ちょうど時間になったので、これで終わりにします。
関連タグ:
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略