Herokuにlaravelで作成したアプリケーションをあげてみる 20181018

# 検索とスコープ


nameで検索できるようにするためPersonController.phpのsearchメソッドを書き換える。

```php5:PersonController.php
public function search(Request $request)
{
    $item = Person::where('name', $request->input)->first();
    $param = ['input' => $request->input, 'item' => $item];
    return view('person.find', $param);
}
```

修正して起動してみると下記の画像の様にnameで検索できる。

<img width="1440" alt="スクリーンショット 2018-10-18 22.38.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/6e3bdf95-1e69-09f6-cb63-00b3e89b9bda.png">

 ちなみに

```php5:PersonController.php
$item = Person::where('name', $request->input)->first();
```

上記のコードでnameの値を検索している。
nameの値が$request->inputと同じ条件を設定している。そしてfirst()で最初のレコードを取得している。

# スコープを利用する

ローカルスコープをよう知るためPersonモデルクラスにメソッドを追加する。

```php5:Person.php
public function scopeNameEqual($query, $str)
{
    return $query->where('name', $str);
}
```

$strの値をwhereして実行した結果をreturnしている。

PersonController.phpのsearchメソッドを書き換える。

```php5:PersonController.php
public function search(Request $request)
{
    $item = Person::nameEqual($request->input)->first();
    $param = ['input' => $request->input, 'item' => $item];
    return view('person.find', $param);
}
```

nameEqualを呼び出せば、nameが指定した名前に絞り込んでレコードを抽出できる。
first()がついているので抽出レコードの一番初めを選択している。
結果は先ほどと同じで名前を検索することができる。

# スコープを組み合わせる
指定した範囲内にあるレコードを検索できる様にしてみる。

Personモデルクラスにメソッドを追加する。

```php5:Person.php
public function scopeAgeGreaterThan($query, $n)
{
    return $query->where('age', '>=', $n);
}

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

scopeAgeGreaterThanは、ageの値が引数の値と等しいもしくは大きいものを絞り込む。
scopeAgeLessThanは、ageの値が引数の値と等しいもしくは小さいものを絞り込む。

PersonController.phpのsearchメソッドを書き換える。

```php5:PersonController.php
public function search(Request $request)
{
    $min = (int)$request->input * 1;
    $max = $min + 10;
    $item = Person::ageGreaterThan($min)->ageLessThan($max)->first();
    $param = ['input' => $request->input, 'item' => $item];
    return view('person.find', $param);
}
```
　画像の様に入力した数値〜+10の範囲で検索できる。
ちなみに(int)$reuqest->inputをしてる理由は、途中で警告が出たため。

<img width="1440" alt="スクリーンショット 2018-10-18 23.32.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/f6ff691c-4a01-5284-21eb-5277a5e6e350.png">

# グローバルスコープを作成してみる
そのモデルでの全てのレコード取得にそのスコープが適用されることをグローバルスコープという。

Person.phpにメソッドを追加する。

```php5:Person.php
use Illuminate\Database\Eloquent\Builder;

protected static function boot()
{
    parent::boot();

    static::addGlobalScope('age', function (Builder $builder) {
        $builder->where('age', '>', 20);
    });
}
```

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

<img width="1440" alt="スクリーンショット 2018-10-18 23.53.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/0d49d572-1f91-6bb3-1e1d-401f0839d47f.png">

#ScopePersonクラスを作る

app/内に「Scopes」とい名前のディレクトリを作成する。
その中に「ScopePerson.php」というファイルを作成する。

```PHP5:ScopePerson.php
<?php
namespace App\Scopes;

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

class ScopePerson implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('age', '>', '20');
    }
}
```

Personクラスのbootメソッドを修正する。

```php5:Person.php
protected static function boot()
{
    parent::boot();

    static::addGlobalScope(new ScopePerson);
}
```

先ほどと同様に20歳以上のレコード選択できていればOK

次回はモデルの保存と更新と削除をやっていこう。