📝

【Laravel】配列文字列をreplaceして検索するスコープ機能

2022/01/16に公開

はじめに

VARCHAR型に以下の形式で登録していくシステムに検索機能を追加した際の対処方法をまとめます

["40","41","42","43","44","45","46","47"]

やり方

Model内で共通利用したいのでScope化する

https://readouble.com/laravel/8.x/ja/eloquent.html

FIND_IN_SET:第1引数の値が第2引数に含まれている場合に範囲を返す
?:ユーザーの入力値を使用するのでプリペアドステートメントでバインドする
replace:カラム名,置換元文字列,置換先文字列を指定する

https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_find-in-set

https://www.tailtension.com/mysql/1467/

"FIND_IN_SET(?,replace(replace(replace({$target_column},'[',''),']',''),'\"',''))", $item);
User.php
public function scopeWhereInByArray($query, $target_column, $ids)
{
    $query->where(function ($subQuery) use ($ids, $target_column) {
        foreach ($ids as $item) {
            $subQuery->orWhereRaw("FIND_IN_SET(?,replace(replace(replace({$target_column},'[',''),']',''),'\"',''))", $item);
        }
    });
}

Scopeをロジックで利用する

UserController.php
// クエリを生成
$query = User::query();

// 都道府県検索
if ($param->getPrefIds()) {
    $query->whereInByArray('pref', $param->getPrefIds());
}

さいごに

読んでいただきありがとうございます。
いいねしていただけると記事執筆の励みになりますので、参考になったと思った方は是非よろしくお願いします!

GitHubで編集を提案

Discussion