Home > front end >  Calling multiple methods of the same class in Laravel
Calling multiple methods of the same class in Laravel

Time:04-14

i was always curious how does Laravel's eloquent work and how they pass many methods in the same line of code. Example: auth()->user()->where(...)->get() In this example they use both methods "where" and "get" So i tried creating the following repository:

class SkillKeyRepository
{
    protected $model;

/**
 * @param SkillKey $model
 */
public function __construct(SkillKey $model)
{
    $this->model = $model;
}

public function all(array $column = []): Collection
{
    return $this->model::all($column);
}

public function where($column, $attribute): SkillKeyRepository
{
    $this->model::where($column, $attribute);
    return $this;
}

public function get()
{
    return $this->model::get();
}
}

After that in my service i tried the following:

class SkillKeyService
{
    use ServiceTrait;
protected $repository;

/**
 * @param SkillKeyRepository $repository
 */
public function __construct(SkillKeyRepository $repository)
{
    $this->repository = $repository;
}

public function get()
{
    dd($this->repository->where('key', 'TagName')->get());
}

The correct result should be a collection of one item. But it's returning all the data from the database and its ignoring the where() funcion and going directly to the get() function.

CodePudding user response:

You just need to get new query builder

class SkillKeyRepository
{
    protected $query;

    /**
     * @param  SkillKey  $model
     */
    public function __construct(SkillKey $model)
    {
        $this->query = $model->newQuery();
    }

    public function all(array $column = []): Collection
    {

        return $this->query::all($column);
    }

    public function where($column, $attribute): SkillKeyRepository
    {
        $this->query::where($column, $attribute);

        return $this;
    }

    public function get()
    {
        return $this->query::get();
    }
}

CodePudding user response:

The problem is you are using the model, to create a query and then trying to chain more to the query using the original model, however this won't work because you need the previously generated query.

The easiest way to do what you want is to actually return the query builder object itself:

class SkillKeyRepository
{
    protected $model;

    /**
     * @param SkillKey $model
     */
    public function __construct(SkillKey $model)
    {
        $this->model = $model;
    }

    public function all(array $column = []): Collection
    {
        return $this->model->all($column);
    }

    public function where($column, $attribute): QueryBuilder
    {
        return $this->model->newQuery()->where($column, $attribute);
    }

}

(new SkillKeyRepository(new SkillKey()))->where('a','b')->get(); // Should work

However you should really take a step back and reconsider what you are doing. Laravel already has the query builder object to do exactly this, why are you trying to re-write it?

  • Related