スコープ機能について

2020/08/12

Laravelで開発して、よく頻出するのがデータベースの操作。

特にクエリービルダーを使ったWhere句はよく使います。

このWere句ですが、よく利用するWhere句の条件式をモデルに定義(スコープ機能)して使いまわすことができます。

今回はLaravelにおけるクエリービルダーのスコープ機能についてエントリーいたします。

 

チュートリアル

以前、作成した「複数キーワード+ページャー機能」のチュートリアルで作成したテーブル構成を利用します。

複数キーワード検索 + ページャー機能 イントロ

 

シナリオ

従業員リストの

・住所が関西
・部署が開発部

この2点の条件式をスコープとして定義してみます。

 

通常のクエリービルダー

Controller

public function scopeDemo()
{
  // 検索QUERY
  $query = Employee::query();

  //結合
  $query->join('depts', function ($query) {
  $query->on('employees.dept_id', '=', 'depts.id');
  });

  //条件式
  $query->where('dept_id','4');
  $query->where(function($q){
  $q->Where('address','like','%'.'大阪府'.'%')
  ->orWhere('address','like','%'.'京都府'.'%')
  ->orWhere('address','like','%'.'兵庫県'.'%')
  ->orWhere('address','like','%'.'滋賀県'.'%')
  ->orWhere('address','like','%'.'奈良県'.'%')
  ->orWhere('address','like','%'.'和歌山県'.'%');
  });

  // ページネーション
  $employees = $query->paginate(10);

  return view('employee.scope_demo')->with('employees',$employees);
}

これでOKです。

 

スコープを使う

関西エリアと開発部の条件式をスコープとして定義します。

スコープはモデルに記述します。

この場合、EloquentでEmployeeのモデルを利用しているのでEmployeeモデルに記述します。

モデル

  //住所のスコープ(関西をセレクト)
  public function scopeFindKansai($query)
  {
  return $query->where(function($q){
  $q->Where('address','like','%'.'大阪府'.'%')
  ->orWhere('address','like','%'.'京都府'.'%')
  ->orWhere('address','like','%'.'兵庫県'.'%')
  ->orWhere('address','like','%'.'滋賀県'.'%')
  ->orWhere('address','like','%'.'奈良県'.'%')
  ->orWhere('address','like','%'.'和歌山県'.'%');
  });
  }

  //部署のスコープ(開発部をセレクト)
  public function scopeFindDevelop($query)
  {
  return $query->where('dept_id','4');
  }
【 point 】メソッド名のつけ方に注目!

 
コントローラ

上記で定義したスコープをコントローラで利用します。

コントローラは先ほどのソースより「条件式」の箇所だけ以下のように書き替えます。

$query = Employee::FindDevelop()->FindKansai()->get();

コントローラは大分すっきりしました。

可読性はあがりますね。

なお、"FindKansai()" と "FindDevelop()" は再利用できます。

一応、ルーティングとビューも載せておきます。

 
ビュー(子)

@extends('layouts.master_employee')
@section('title', '従業員リスト')

@section('table')
  <table class="table table-striped">
  <tr>
  <th>部署</th>
  <th>従業員名</th>
  <th>住所</th>
  <th>メールアドレス</th>
  <th>年齢</th>
  <th>電話番号</th>
  </tr>
  <!-- loop -->
  @foreach($employees as $employee)
  <tr>
  <td>{{$employee->dept_name}}</td>
  <td>{{$employee->name}}</td>
  <td>{{$employee->address}}</td>
  <td>{{$employee->email}}</td>
  <td>{{$employee->old}}</td>
  <td>{{$employee->tel}}</td>
  </tr>
  @endforeach
</table>

  <!-- pager -->
  <div class="paginate text-center">
  {!! $employees->render() !!}
  </div>

@endsection

親となる継承先のテンプレートは以前やったチュートリアルと同じものを使います。

STEP3.複数検索ページ作成

 
ルーティング

# スコープテスト
Route::get('employee/scope_demo','EmployeeController@scopeDemo');

 

ブラウザ確認

上のように表示されていればOKです。

一応、SQLも確認してみます。

 

SQL確認

あまり綺麗なやり方ではないですが。。とりあえず簡易的なやり方です。

コントローラのページャーの箇所を以下に修正します。

  // ページネーション
  //$employees = $query->paginate(10);
  $query->paginate(10);
  $employees =$query->toSql();
  dd($employees);
【 解説 】
dd()・・・die() + var_dump()
dd()は与えられた変数をダンプして、スクリプトを止める働きをします。

プレースホルダが "?" のままですが、SQLの内容はこれで確認できます。

スコープ機能については以上です。

 

PHPフレームワーク Laravel入門 第2版

僕がはじめてLaravelを学習するために参考にしたサイトは、掌田津耶乃(しょうだつやの)さんの libro というサイトです。当時(2016年)、Laravel学習サイトの中でもこのサイトは群を抜いてわかりやすく説明されていたので、とても勉強になったのを覚えています。この本は掌田津耶乃さんが書いた本なので、わかりやすく解説されているだろうと kindle で購入しました。2020年8月の時点でいうと日本国内にて唯一の Laravel の良書と言っても良いかと思います。口コミでもLaravel本のロングセラー定番解説書として認知されています。当サイトではチュートリアル形式でLaravelを解説しているので、初心者の方はこの本とセットで学習されるといいと思います。しかし、かなりわかりやすく解説されているとはいえ、PHP中級者以上のスキルは必要です。PHP自体の知識が乏しい方は 独習PHP 第3版 をあわせて購入することをお勧めします。

Amazonで詳細を見る

オススメ

 

本庄マサノリ

仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら

>> Twitter をフォローする

 

-基礎知識