BLOG

ブログ

2022/03/14 プログラミング技術系

フレームワーク未経験者がLaravelのORMに感動した話

この記事を書いた人 M.Y
画像1

はじめまして!12月よりウイングドアのメンバーに加わりました、M.Yです。
今回は、LaravelのORMの便利さについて実体験をもとに共有できたらと思います!

私が今まで経験した開発現場では、主にネイティブなPHPもしくはガラパゴスなフレームワークやライブラリを使用することがほとんどでした。
そのため、各所から「すごいぞ!」と噂は聞いていたORMに今回初めて触ることになったのです。

ORMとは?

参考サイト:O/Rマッピング 【Object/RDB mapping】 O/Rマッパー / O/R mapper / ORM

Object-relational mapping:オブジェクト関係マッピング(オブジェクト指向における)オブジェクトと関係(リレーショナルデータベース)との対応付けを行うもの
とありますが、ちょっと解像度が低くてピンとこない様な気がするのは私だけでしょうか・・・😅

実際、私が直面した出来事をもとに解説していきたいと思います。

どこにも定義されていないメソッドが呼ばれている?

ある時、既存システムとして動いている案件のソースコードを見ながら、似た機能を実装しようとしていた時のこと。

Call to undefined method Illuminate\Database\Query\Builder::createOrderWord() 

と突然のエラー。
(はいはい、createOrderWordメソッドが呼べなかったのね。Shift+Command+F->「createOrderWord()」->Enter(ターン!))………

ない🤔

そんなメソッドがないんです。似た名前のメソッドはあるんだけど。。。うーん。。。。
しばらく悩みに悩んで、プロジェクトメンバーに相談したところ『Laravelのスコープという機能での書き方』を教えていただきました。

ローカルスコープって?

Laravelのドキュメントにはこう書いてあります。

ローカルスコープによりアプリケーション全体で簡単に再利用可能な、一連の共通制約を定義できます。
たとえば、人気のある(popular)ユーザーを全員取得する必要が、しばしばあるとしましょう。スコープを定義するには、scopeを先頭につけた、Eloquentモデルのメソッドを定義します。

スコープはいつもクエリビルダインスタンスを返します。
(中略)

スコープが定義できたらモデルのクエリ時にスコープメソッドを呼び出せます。しかし、メソッドを呼び出すときはscopeプレフィックスをつけないでください。

参考サイト:Laravel 7.x Eloquent:利用の開始-ローカルスコープ

参考にしようとしていた機能(createWhereWord())のコードを見てみると…
scopeを先頭につけた、Eloquentモデルのメソッドを定義…💡いました!

public function scopeCreateWhereWord($builder, $queries) {
    return $builder->where('user_id', $queries['user_id']);
}

「似た名前のメソッドはあるんだけど」というのはある意味正しかったのです。

上記は「クエリビルダでwhere文を作成する」処理の一例で、user_idフィールドが$queries['user_id']と一致するものを取得するという処理ですが、これを呼び出すときは

createWhereWord($builder, $queries);

の形(scopeプレフィックスをつけない)で呼び出すことができるのです!!✨
これこそが今回私が陥ったエラーの原因『メソッドを呼び出すときはscopeプレフィックスをつけない』 ということでした。
この規則を知らず、scopeCreateOrderWord()を実装していなかったことが今回のエラーの原因でした。(ドキュメントを読むの本当に大事、反省…)

しかも以下のように書くと、order byされたデータを取得することができるメソッドをチェーンでつなぎ、呼び出すこともできます。

public function scopeCreateWhereWord($builder, $queries) {
    return $builder->where('user_id', $queries['user_id'])->orderBy('user_id', 'desc');
}

上記のコードは先ほどのコードに->orderBy('user_id', 'desc') を追記したものです。
これによりクエリビルダがorderBy user_id desc をクエリに追加してくれるので、毎回orderByをつけたwhere文を作成しなくてもcreateWhereWordを呼び出すだけで求めている結果が得られるのです🙌

ORMって何が便利なの?

前述の通り、私が今まで携わった開発では既存フレームワークを使っていないため、どうしていたかというと

  1. DTO作成
  2. DAOクラス内に生のSQLを記述(プレースホルダの値が複数ある場合大変だった)
  3. 必ずDTOを通すことでDBのデータ型の担保

などしていました。
それが、ORMになると

  1. DBからのデータの取得
  2. 取得したデータのオブジェクト化
  3. CRUDしたデータをDBに格納

を意識することなく、しかもSQL自体書かずに実装することができる印象です。
ORMについて書かれている記事などを見てみると、

  • 頻繁に利用するクエリ条件を1箇所にアクセスしやすい形でまとめることができる
  • アプリケーション側はDBが何であるかを意識する必要がなくなる(疎結合である、と言われる)
    • DB自体を変更するようなことがあっても、SQL文の書き換えの必要がない(そもそもSQLを書かない)

というメリットを目にすることが多かったです。
日々の開発において「アクセスしやすさ」という恩恵を受けることが、どれだけ開発コストを軽くしてくれるかということを、きっとORMを使っていただくことで実感していただけると思います😀

余談ですが、Laravelに用意されているdd(dump & die のこと)メソッドで

dd($query->toSql(), $query->getBindings());

とすれば、実行されるSQLもBindされる値も一目瞭然!テストする時もとても便利です👏

まとめ

まだ使い始めて間もないORMですが、

  • ローカルスコープは、モデルにscope+メソッド名 で定義して使用できるようになる
    • 呼び出すときは`scope`を除いたメソッド名で呼び出す
  • 型を意識する必要なくオブジェクトとしてDBにアクセスできる
  • SQLを書かなくて良くなるからコードがすっきりする

というだけでも私の中での大革命でした⚡️サンキューLaravel!😙サンキューORM!😄

楽しいですね、Laravel。
日本語ドキュメントが豊富ですし、技術ブログも星の数ほどあるので、躓いてもすぐに解決しやすいです!
「PHPのフレームワークって何から始めたらいいかわからない😣」という方にも、是非おすすめのフレームワークです👍

最近使い始めたばかりのLaravelにすっかり虜のM.Yでした。

参考サイト:Laravel 7.x Eloquent クエリスコープ

参考サイト:【Laravel】ローカルスコープから考える要求と意図



株式会社ウイングドアは福岡のシステム開発会社です。
現在、私達と一緒に"楽しく仕事が出来る仲間"として、新卒・中途採用を絶賛募集しています!
ウイングドアの仲間達となら楽しく仕事できるかも?と興味をもった方、
お気軽にお問合せ下さい!

アーカイブ