be-codified
be-codified

Reputation: 6124

Laravel: dynamic where clause with Elouquent

I am calling URL with search params which are dynamic. How could I form proper Eloquent query?

In theory:

  1. query
  2. query where(someParam1)
  3. query where(someParam2)
  4. query orderby(someParam3)
  5. query get

I need this kind of structure so I can use where clause if param exists. If there is some other way in Laravel, please let me know.

Upvotes: 38

Views: 42034

Answers (6)

Guilherme
Guilherme

Reputation: 3

You can pass a callback to the where function.

So, you can do something like this:

class TestService {

   TestRepository $testeRepository;

   public function __construct(TesteRepository $teste) {
      $this->testeRepository = $teste;
   }

   public function getAll(array $filters)
   {
      $where = function (Builder $query) use ($filters) {
         collect($filters)
            ->each(function ($value, $param) use ($query) {
               if ($param === 'test') {
                  $query->where($param, '=', $value); 
               } else if ($param === 'test2') {
                  $query->orWhere($param, '>', $value);
               }
            });
      };
      return $this->testRepository->gelAll($where);
   }

class TestRepository
{
   public function getAll(\Closure $where)
   {
        $query = TestModel::query();
        $query->where($where);
        //and put more stuff here, like:
        //$query->limit(15)->offset(30)
        ...
       return $query->get();
   }
}

And in your controller you pass the filters:

class TestControler ...
{
    public function $index()
    {
       $filters = request()->query();
       return $this->testService->getAll($filters);
    }
}

Upvotes: 0

Koushik Das
Koushik Das

Reputation: 10793

You can just use the where statement. For ex: on users table or User model, you want dynamic search on name, id. You can do this

$where = [];
$firstName = $request->get('first_name');
if ($firstName) $where[] = ['first_name', 'like'. '%' . $firstName . '%'];
$id = $request->get('id');
if ($id) $where[] = ['id', $id];
$users = User::where($where)->get();

By default, it will return all the users, if anything exists in $where array, it will apply the where condition on that.

Upvotes: 9

CTully12
CTully12

Reputation: 73

I came here from Google. If you are going to be iterating over more then 5 if statements, its more effective to use a switch statement

 if(empty($request->except('_token')))
        return 'false';

    $models = Vehicle::query();
    $request_query = $request->all();
    $year_switch = false;

    foreach ($request_query as $key => $field_value){



        if($field_value != 'any'){                
            switch($field_value){
                case 'X':                                            
                case 'Y':
                    $year_switch = true; 
                break;
                case'Z':
                    //Dynamic
                    $models->where($key,'LIKE', $field_value);
                break;

            }                    
        }
    }

Upvotes: 0

Nishabh Mistry
Nishabh Mistry

Reputation: 59

You can use like this

$validateUserDetail = User::query();
if (!empty($userDetails['email'])) {
    $validateUserDetail->whereemail($userDetails['email']);
}if (!empty($userDetails['cellphone'])) {
    $validateUserDetail->wherecellphone($userDetails['cellphone']);
}
$validateUserDetail->select('username');
$validateUserDetail->get()

Upvotes: 2

JasonJensenDev
JasonJensenDev

Reputation: 2407

It's easy with Laravel. Just do something like this:

$query = User::query();

if ($this == $that) {
  $query = $query->where('this', 'that');
}

if ($this == $another_thing) {
  $query = $query->where('this', 'another_thing');
}

if ($this == $yet_another_thing) {
  $query = $query->orderBy('this');
}

$results = $query->get();

Upvotes: 99

Nikunj K.
Nikunj K.

Reputation: 9199

You can pass dynamic value by below example

$user_auctions = $this->with('userAuctions')
                ->where('users.id', '=', $id)
                ->get();

Upvotes: 0

Related Questions