Eloquent's dynamic scope search trait

Submitted by reymark-torres - 5 years ago

If you want your search functionality to be dynamic as possible to avoid code repetitions, you can use this trait directly in your models

// app/Models/Shared/CanSearch.php - This is a trait that can be used by any models

public function scopeSearch($query, $keyword, $columns = [], $relativeTables = [])
{
    if (empty($columns)) {
        $columns = array_except(
            Schema::getColumnListing($this->table), $this->guarded
        );
    }   

    $query->where(function ($query) use ($keyword, $columns) {
        foreach ($columns as $key => $column) {
            $clause = $key == 0 ? 'where' : 'orWhere';
            $query->$clause($column, "LIKE", "%$keyword%");
                
            if (!empty($relativeTables)) {
                $this->filterByRelationship($query, $keyword, $relativeTables);
            }
        }
    });

    return $query;
}


private function filterByRelationship($query, $keyword, $relativeTables)
{
    foreach ($relativeTables as $relationship => $relativeColumns) {
        $query->orWhereHas($relationship, function($relationQuery) use ($keyword, $relativeColumns) {
            foreach ($relativeColumns as $key => $column) {
                $clause = $key == 0 ? 'where' : 'orWhere';
                $relationQuery->$clause($column, "LIKE", "%$keyword%");
            }
        });
    }

    return $query;
}