l5-repository
l5-repository copied to clipboard
Why my Criteria not apply?
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!
I tried to overwrite makeModel() like this and it works with Laravel 5.3.
public function makeModel()
{
parent::makeModel();
$this->model=$this->model->newQuery();
}
It works with @quynhbkit fix, but where is problem ? Maybe there is a bug ?
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
Hi! Does anyone solve the bug?! I'm using Laravel 5.2 and I've also encounter this bug.
Same problem, criteria is not applied. I tried following:
- With
MyModel::where(...)
, where conditions applied. - 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.
@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 Thank you for your solution. I will try it when I have time.
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}%");
});
}
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);
}
}