検索とスコープ

whereによる検索

 複数のレコード取得

$変数 =モデルクラス :: where(フィールド名,値)->get();

最初のレコード取得

$変数 =モデルクラス :: where(フィールド名,値)->first();

 

nameを検索

「Serch」メソッドを書き換える。

<?php

namespace App\Http\Controllers;

use App\abc;
use Illuminate\Http\Request;

class abcController extends Controller
{
    public function index(Request $request)
    {
       $items = abc::all();
       return view('abc.index',['items' => $item]);
    }
    
    public function find(Request $request)
    {
       return view('abc.find',['input' => '']);
    }
    
    public function search(Request $request)
    {
       $item = abc::where('name',$request->input)->first();
       $prm = ['input' => $request->input'item' =>$item];
       return view('abc.find',$prm);
    }
}

 /abc/findにアクセス。

テキストに名前を入力後検索をクリックし、レコードの検索が表示。

f:id:mkyosuke:20200110170215p:plain

スコープ

 スコープとは、特定の条件でレコードを検索する。

モデルのスコープは、モデルの範囲を特定するもの。

 

ローカルスコープ

 モデルの中にメソッドを入れ、必要な時に使う。

public function scope 名前 ($query, 引数)

{

  ----必要な処理-----

return 絞り込んだビルダ;

}

 

nameをスコープする

 abcモデルクラスに以下のようなメソッドを追加。

public function scopeNameAbc($query, $abc)
{
    return $query-where('name'$abc);
}

第2引数に$abcを利用して、$query->where('name', $abc);を実行した結果がreturnする。

nameの値が$abcであるBuilderインスタンスが返される。

 

NameAbcを利用

 abcContorollerクラスのsearchメソッドを以下に修正

    public function search(Request $request)
    {
       $item = abc::nameAbc($request->input)->first();
       $prm = ['input' => $request->input'item' =>$item];
       return view('abc.find',$prm);
    }

 

/abc/findにアクセス。

名前を検索

 

f:id:mkyosuke:20200111011542p:plain

nameAbc($request->input)

スコープ用のメソッドを呼び出す場合は、メソッド名の最初のscopeは不要。

 

スコープを組み合わせる

 数字の値を「〇〇以上〇〇以下」というスコープを作成。

abcモデルクラスにスコープ用メソッドを追加。

public function scopeAgBig($query, $n)
{
    return $query->where('age','>=',$n);
}

public function  scopeAgSmall($query, $n)
{
    return $query->where('age','<=',$n);
}
}

scopeAgBigは、ageの値が引数の値と等しいか大きい

scopeAgSmallは、ageの値が引数の値と等しいか小さい

2つ組み合わせる➡「〇〇以上〇〇以下」となる。

次に、abcContorollerクラスのsearchメソッドを以下に書き換え

    public function search(Request $request)
    {
       $mini = $request->input * 1;
       $mx =$mini + 10;
       $item = abc::ageBig($mini->ageSmall($mx)->first();
       $prm = ['input' => $request->input'item' =>$item];
       return view('abc.find',$prm);
    }

 

/abc/findにアクセス。

数字を入力して検索➡入力して数字~+10の範囲のレコードが表示

f:id:mkyosuke:20200111020825p:plain

abcContollerからageBigとageSmallを2つ並べて呼び出すと「〇〇以上〇〇以下」の検索条件となる。

firstで最初のレコード取得。whereを使わず、メソッドだけでレコードの検索が可能。

       $item = abc::ageBig($mini)->ageSmall($mx)->first();

 

グローバルスコープ

 ■Bootメソッド

モデルの初期化メソッド

protected static function boot()
{
   parent::boot();
   ---初期化処理----
}

静的メソッドになるので、モデルのインスタンスを利用ができない。

グローバルスコープ(を追加)にするために「addGlobalScope」という静的メソッドを使う。


static::addGlobalScope(スコープ名,function(Builder $builder)
{
   -----検索処理-----
}

 

グローバルスコープを作成する

 ageの値が20以上のレコード表示。

モデルクラスにbootメソッドをオーバーライド。

モデルクラス abc.phpにメソッドを追加。

protected static funtion boot()
{
   parent::boot();
   
   static::addGlobalScope('age'function (Builder $builder) {
      $builder->where('age','>',20);
   });
}

 

/abcにアクセス

f:id:mkyosuke:20200114145653p:plain

Scopeクラスを作成

 Scopeクラス

Illumate\Database\EloquentにあるScopeを実装して定義されるクラス。

class クラス名 implements scope
{
    public function apply(Builder $builder, Model $model)
    {
        ----検索処理----
    }
}

 「apply」メソッド。BuilderとModelがインスタンスとして渡される。

 引数を使い検索処理を行う。

 

ScopeAbcクラス

「app」フォルダの「Scopes」でスクリプトフォルダ作成。

 「ScopeAbc.php」を作成

<?php
namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class ScopeAbc implements Scope
{
    public function apply(Builder $builderModel $model)
    {
        $builder->where('age''>'20);
    }
}

applyメソッドで$builder->where('age','>',20);を実行しているのと、同じ。

 

Abcモデルクラスの修正

下記をソースコードを追加。

use App\Scopes\ScopeAbc;

Abcクラスのbootメソッド

ScopeAbcがグローバルスコープとして追加

    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope(new ScopeAbc);
    }
}

/abcにアクセス。20歳以上のレコードが表示される。