Search code examples
phplaraveleloquentlaravel-7eloquent-relationship

Get relationship data from eloquent builder laravel 7


I wanna filter my table data. I have a table for states, one for cities and one for students.

  1. states(id, name)
  2. cities(id, name, state_id)
  3. students(id, first_name, last_name, city_id)

When I wanna filter data with eloquent builder how can I access relationships for handle state filter.

<?php

namespace App\StudentSearch\Filters;

use Illuminate\Database\Eloquent\Builder;

class StateId implements Filter
{
    /**
     * @inheritDoc
     */
    public static function apply(Builder $builder, $value)
    {
        // something like this
        return $builder->where('state_id', $value);
    }
}

StudentSearch.php

<?php

namespace App\StudentSearch;

use App\Student;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;

class StudentSearch
{
    public static function apply(Request $filters)
    {
        $query = static::applyDecoratorsFromRequest($filters, (new Student)->newQuery());

        return static::getResults($query);
    }


    private static function applyDecoratorsFromRequest(Request $request, Builder $query)
    {
        foreach ($request->all() as $filterName => $value) {

            $decorator = static::createFilterDecorator($filterName);

            if (static::isValidDecorator($decorator)) {
                $query = $decorator::apply($query, $value);
            }

        }
        return $query;
    }
    private static function createFilterDecorator($name)
    {
        return __NAMESPACE__ . '\\Filters\\' . Str::studly($name);
    }

    private static function isValidDecorator($decorator)
    {
        return class_exists($decorator);
    }

    private static function getResults(Builder $query)
    {
        return $query->get();
    }
}

Note that relations between tables is completely defined in models.


Solution

  • I found the solution.

    We can do this with eloquent builder:

    $builder->whereHas('relationName', function($query) use($value) {
        $query->where('state_id', $value);
    });
    

    Link to source