l5-repository icon indicating copy to clipboard operation
l5-repository copied to clipboard

Why my Criteria not apply?

Open MarlonEtiene opened this issue 8 years ago • 9 comments

Hello guys, Can anyone inspect this code and help me to understand why my criteria not apply? My Criteria:

<?php namespace EstudioLMS\Repositories\Auth;

use Prettus\Repository\Contracts\RepositoryInterface;
use Prettus\Repository\Contracts\CriteriaInterface;

class UserCriteria implements CriteriaInterface
{

    public function apply($model, RepositoryInterface $repository)
    {
        $model = $model->where('show_admin', '=', false);
        return $model;
    }
}

My Repository:

<?php
namespace EstudioLMS\Repositories\Auth;

use EstudioLMS\Models\Auth\User;
use Illuminate\Support\Facades\Auth;
use Prettus\Repository\Eloquent\BaseRepository;

/**
 * Class UserRepositoryEloquent
 * @package EstudioLMS\Repositories\Auth
 */
class UserRepositoryEloquent extends BaseRepository implements UserRepository
{

    public function boot()
    {
        $role = Auth::user()['roles'][0]['name'];
        if ($role !== 'owner') {
            $this->pushCriteria(new UserCriteria());
        }
    }

    /**
     * Specify Model class name
     *
     * @return string
     */
    public function model()
    {
        return User::class;
    }

But when I login with user with role !== 'owner' the criteria not apply Help me please!

MarlonEtiene avatar Sep 01 '16 20:09 MarlonEtiene

I tried to overwrite makeModel() like this and it works with Laravel 5.3.

public function makeModel()
{
    parent::makeModel();
    $this->model=$this->model->newQuery();
}

quynhbkit avatar Sep 23 '16 16:09 quynhbkit

It works with @quynhbkit fix, but where is problem ? Maybe there is a bug ?

ghost avatar Oct 04 '16 21:10 ghost

It works with @quynhbkit fix, but I get a new error if I try to create a new instance with $this->userRepository->create($request->all())

BadMethodCallException: Call to undefined method Illuminate\Database\Query\Builder::newInstance() in /opt/project/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2508

stephane-monnot avatar Mar 15 '17 15:03 stephane-monnot

Hi! Does anyone solve the bug?! I'm using Laravel 5.2 and I've also encounter this bug.

geraldarcega avatar Apr 10 '17 07:04 geraldarcega

Same problem, criteria is not applied. I tried following:

  1. With MyModel::where(...), where conditions applied.
  2. With app(MyModel::class)->where(...), where conditions not applied, which is now the way how the criteria is applied.

The difference here is that, 1 is Query Builder, and 2 is Eloquent Builder which is a wrapper of Query Builder.

From what I see here, Eloquent Builder has to start with newQuery(), so the query gets built.

tsunamilx avatar Apr 26 '17 07:04 tsunamilx

@stephane-monnot may be you can put $this->model->newQuery(); into applyCriteria instead of makeModel


    /**
     * Apply criteria in current Query
     *
     * @return $this
     */
    protected function applyCriteria()
    {
        if ($this->skipCriteria === true) {
            return $this;
        }
        $criteria = $this->getCriteria();

        if ($this->model instanceof Model) {
            $this->model = $this->model->newQuery();
        }

        if ($criteria) {
            foreach ($criteria as $c) {
                if ($c instanceof CriteriaInterface) {
                    $this->model = $c->apply($this->model, $this);
                }
            }
        }
        return $this;
    }

lvqingan avatar Apr 27 '18 09:04 lvqingan

@lvqingan Thank you for your solution. I will try it when I have time.

stephane-monnot avatar Apr 27 '18 09:04 stephane-monnot

in laravel 5.5

AdminUserController:

$this->repository->setPresenter(AdminUserPresenter::class);
$this->repository->pushCriteria(AdminUserCriteria::class);

return response()->json($this->repository->search($request));

AdminUserRepository :

public function search(Request $request)
{
    $this->applyCriteria();    //important
    $condition = $this->model;

    $data['total'] = $condition->count();

    $data['data'] = $this->parserResult(
        $condition->offset($request->get('offset'))->limit($request->get('limit'))->get()
    );


    return $data;
}

AdminUserCriteria :

public function apply($model, RepositoryInterface $repository)
{
    $keyword = request('search');
    return $model->when($keyword,function ($query)use($keyword){
        return $query->where('name','like',"%{$keyword}%");
    });
}

jwwb681232 avatar May 20 '18 14:05 jwwb681232

try this:

<?php namespace EstudioLMS\Repositories\Auth;

use Prettus\Repository\Contracts\RepositoryInterface;
use Prettus\Repository\Contracts\CriteriaInterface;

class UserCriteria implements CriteriaInterface
{

    public function apply($model, RepositoryInterface $repository)
    {
        return  $model->where('show_admin', '=', false);
    }
}

drmovi avatar Dec 10 '21 14:12 drmovi