Laravel Modelを””複数条件””で検索を色々/whereIn/orWhere/orWhereHas/function($query)

Modelを複数条件で抽出際の方法解説します。
複数条件といっても様々な複数条件が存在するかと思います。
使用用途別に解説していけたらと思います。

①:複数のカラムで、’どれか’のカラムの検索条件に合致する場合

orWhereを利用します。

sex, age, 複数カラムで検索をしています。

Human::
    where('sex', 'men')
    ->orWhere('age', '>=', 40)
    ->get();

②:特定のカラムで、複数の検索条件の’どれか’に該当

whereInを利用します。

Human::
    whereIn('age', [30,31,32,33,40,41,42,43])
    ->get();

ageカラムの中で、該当するものを抽出します。

③:複数のカラムで、複数の検索条件に該当する場合

whereInをorWhereで接続して利用します。 

$nationality = ['japan', 'china', 'korean'];

Human::
    whereIn('age', [30,31,32,33,40,41,42,43])
    ->orWhere(function($query) use($nationality) {
            $query->whereIn('nationality',$nationality);
        })
    ->get();

④:複数テーブルで、’どれか’の検索条件に該当

下記記事にて記述しています。

複数テーブルと書いていますが、厳密には1つのModelからリレーション先のデータを他のテーブルデータとして捉えています。

⑤:複数テーブルで、複数カラムの検索条件に該当

EducationalBackground
 の国が$countries含まれる OR 専攻が$magersに含まれる
OR
Job
 の専門性が$specialtiesに含まれる

Human::
    whereHas('EducationalBackground', function ($query) use($countries, $magers) {

        return $query->whereIn('country',$countries);
                    ->orWhere(function($query) use($magers) {
                        $query->whereIn('mager',$magers);
                    });
    })
    ->orWhereHas('Job', function ($query) use($specialties) {
        return $query->whereIn('specialty',$specialties);
    })
    ->get();

1つのModelからリレーション先の検索ORカラム検索にヒットしたデータを抽出 / Eloquent/with/orWhere

LaravelのEloquentを利用して、複数の条件でデータ抽出をします。下記の① OR ② の抽出です。

①:Modelのカラムから条件を指定
②:リレーション先の条件を指定

・利用するシチュエーション

例えば、検索窓を設置した場合。
「映画タイトル」OR「映画のハッシュタグ」どちらかにヒットさせる検索窓にする場合などです。

・Model

Movie Model と Tag Model それを繋ぐリレーションを記載しています。

①:Movie Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Movie extends Model
{
    use HasFactory;

    protected $fillable = [
        'movie_title',
    ];

    public function tags()
    {        
        return $this-->hasMany(Tag::class);
    }    
}

②:Movie Tag

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    use HasFactory;

    protected $fillable = [
        'tag_name',
        'movie_id',
    ];

}

Controllerの処理

実際にControllerで抽出する条件を書いていきます。

public function search($words)
{
    
    $movie = Movie::with('tags')
    ->whereHas('tags', function ($query) use ($words) {
            return $query->where('tag_name', "LIKE", "%".$words."%");
        })
    ->orWhere('movie_title', "LIKE", "%".$words."%")
    ->get();

    return $movie;

}

・リレーション先の条件を抽出する with 
・Or条件で抽出する orWhere
を併用することで、実装可能です。

検索窓に、映画のタイトルを検索しても、ハッシュタグを検索しても、どちらかにヒットする movie Modelのデータが抽出されます。

Laravelのwherehasで複数のリレーションを繋げてデータ取得する方法

「Laravelのwherehasで複数のリレーションを繋げてデータ取得する方法」というタイトルですが、もう少し詳細に伝えると、
リレーションがネスト化しているデータをwherehasで条件指定してから取得する方法です。

リレーションがネスト化している??一体どういうことと思う方もいるかもしれません。

例えば、
user -> posts がリレーションされていて
posts -> comments がリレーションされている場合です。

今回やりたいことは、user -> post -> comment と一括でつなぎます。
userデータを「commentデータを条件」に取得することです。
例えば、commentで、「よろしく」と言っている条件に絞って、userデータを取得する。と言った感じです。

実際の取得方法では、下記です。
※posts, comments はリレーション名称です。

$commentUser = User::with('posts.comments')
    ->whereHas('posts.comments', function ($query) {
     return $query->where('message', "よろしく");
    })
    ->get();

ネストしたリレーションを取得する場合のポイントは1つです。
リレーションネストを. でつなぎます。

with('posts.comments')
whereHas('posts.comments', function ($query)

と言った感じです。
ご活用下さいませ。

リレーションを利用したデータ取得に関しては下記もご参考下さい。