0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel Eloquent で SELECT 処理を共通化する方法

Posted at

Laravel Eloquent で SELECT 処理を共通化する方法

はじめに

Laravel の Eloquent を使ってデータを取得する際、 where 句を使ったクエリを何度も書くことが多いです。たとえば、以下のようなコードを頻繁に書くことになります。

$customers = Customer::where('status', 'active')
    ->where('age', '>=', 30)
    ->get();

これを 共通メソッド にまとめることで、可読性や保守性を向上させる方法を紹介します。


設計の方針

共通の selectCustomers() メソッドを作成し、

  • さまざまな検索条件equalnot_equalin など)を指定可能
  • 取得方法をオプションで指定first()get()paginate() など)
  • 条件を増やしてもコードの可読性を保つ

ようにします。


キー名の設計

検索条件を配列のキーとして統一し、以下のように指定できるようにします。

キー名 SQL演算子
equal = 'equal' => ['status' => 'active']
not_equal != 'not_equal' => ['status' => 'inactive']
in IN 'in' => ['id' => [1, 2, 3]]
not_in NOT IN 'not_in' => ['id' => [4, 5, 6]]
greater > 'greater' => ['age' => 18]
greater_or_equal >= 'greater_or_equal' => ['age' => 20]
less < 'less' => ['age' => 60]
less_or_equal <= 'less_or_equal' => ['age' => 65]
like LIKE 'like' => ['name' => '%田%']
between BETWEEN 'between' => ['price' => [100, 500]]
is_null IS NULL 'is_null' => ['deleted_at']

共通メソッドの実装

use App\Models\Customer;

function selectCustomers(array $conditions = [], array $options = [])
{
    $query = Customer::query();

    if (!empty($conditions['equal'])) {
        foreach ($conditions['equal'] as $column => $value) {
            $query->where($column, $value);
        }
    }

    if (!empty($conditions['not_equal'])) {
        foreach ($conditions['not_equal'] as $column => $value) {
            $query->where($column, '!=', $value);
        }
    }

    if (!empty($conditions['in'])) {
        foreach ($conditions['in'] as $column => $values) {
            $query->whereIn($column, $values);
        }
    }

    if (!empty($conditions['greater'])) {
        foreach ($conditions['greater'] as $column => $value) {
            $query->where($column, '>', $value);
        }
    }

    if (!empty($conditions['like'])) {
        foreach ($conditions['like'] as $column => $value) {
            $query->where($column, 'LIKE', $value);
        }
    }

    if (!empty($conditions['is_null'])) {
        foreach ($conditions['is_null'] as $column) {
            $query->whereNull($column);
        }
    }

    // オプション処理
    if (!empty($options['orderBy'])) {
        $query->orderBy($options['orderBy'], $options['direction'] ?? 'asc');
    }

    if (!empty($options['first'])) {
        return $query->first();
    } elseif (!empty($options['paginate'])) {
        return $query->paginate($options['paginate']);
    } elseif (!empty($options['limit'])) {
        return $query->limit($options['limit'])->get();
    }

    return $query->get();
}

使用例

1. statusactive かつ age が 30 以上のデータを取得

$customers = selectCustomers([
    'equal' => ['status' => 'active'],
    'greater_or_equal' => ['age' => 30]
]);

2. id1, 2, 3 に含まれるが、deleted_atNULL のデータを取得

$customers = selectCustomers([
    'in' => ['id' => [1, 2, 3]],
    'is_null' => ['deleted_at']
]);

3. 名前に「田」が含まれるデータを 10件 取得

$customers = selectCustomers([
    'like' => ['name' => '%田%']
], ['limit' => 10]);

まとめ

このように、 selectCustomers() を作成することで、

共通化により、コードの重複を削減
柔軟な検索条件を指定可能
拡張しやすい設計

というメリットがあります。Eloquent の活用をよりスムーズにするため、ぜひ参考にしてください!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?