JR Prajapati
12 May, 2021

Method Illuminate\Database\Eloquent\Collection::orwhere does not exist. Can't find a better solution online.

1 Answer         7957 Views

Jiwan Thapa
12 May, 2021

This laravel error occurs when you try to use orWhere on collections like get() or all(). This generally happens especially in search queries where you want to retrieve data depending upon multiple conditions and you don't know how to write the base query and concatenate the clauses if certain conditions meet.

Recently, I was working on a school management system where I exactly went through the same scenario and here you can find what I did.

I had four search filters namely year, class, gender and search string where the default value for year, class and gender is set as all.

So, I retrieved those values on the method getStudents() on my studentController as shown below:

public function getStudents(Request $request){
  $year = $request->year;
  $class = $request->grade;
  $gender = $request->gender;
  $text = $request->text;  
} 

Here, the requirement was to retrieve related data if any of the value is not empty. And, if you manually write all the conditions, then, there will be 15 different algorithms/conditions and you would need to write search query for each of those algorithms. And, that would of course, be tedious and won't look good too.

The best way to go would be to create a select query and add conditions within the query itself, so that, a single query would work on all 15 situations.

So, my base query would be:

$result = student::orderby('fname','ASC')->get();

And, the conditions that would follow would be:

1. If the year value is set, then, I would concatenate the clause:

if($year != 'all'){
	$result = $result->where('year',$year);
}

2. If the class value is set, then, further, I would concatenate the clause:

if($class != 'all'){
	$result = $result->where('class',$class);
}

3. If the gender value is set, then, further, I would concatenate the clause:

if($gender != 'all'){
	$result = $result->where('gender',$gender);
}

4. If the text value is not empty, then, further, I would concatenate the clause:

if($text != ''){
  $result = $result->where(function($q) use ($text){
    $q->where('fname','LIKE','%'.$text.'%')->orwhere('lname','LIKE','%'.$text.'%')->orwhere('address','LIKE','%'.$text.'%');
  });
}

Now, the problem would be that, I added the clause orwhere after get() and that would throw an exception of Method Illuminate\Database\Eloquent\Collection::orwhere does not exist. And, that's because, we can't add orwhere after collection instances like all() or get().

So, the way to get around this is to remove the collection instance get() from the initial query and concatenate it at the end of the clause as shown below:

$result = $result->get();

Here's the complete solution code for Method Illuminate\Database\Eloquent\Collection::orwhere does not exist in a single block.

public function getStudents(Request $request){
  $year = $request->year;
  $class = $request->grade;
  $gender = $request->gender;
  $text = $request->text; 

  $result = student::orderby('fname','ASC');
  if($year != 'all'){
  	$result = $result->where('year',$year);
  }
  if($class != 'all'){
  	$result = $result->where('class',$class);
  }
  if($gender != 'all'){
  	$result = $result->where('gender',$gender);
  }
  if($text != ''){
  	$result = $result->where(function($q) use ($text){
	  $q->where('fname','LIKE','%'.$text.'%')->orwhere('lname','LIKE','%'.$text.'%')->orwhere('address','LIKE','%'.$text.'%');
	});
  }
  $result = $result->get();
  if(count($result) > 0){
  	//show your result here...
  }
}

Hope, this answer gives you a better insight on how to overcome the Method Illuminate\Database\Eloquent\Collection::orwhere does not exist error in laravel with great ease. Let me know through the comments, if you still couldn't find a way through.


0 Like         0 Dislike         0 Comment        


Leave a comment