Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel search query with multiple conditions

Tags:

php

laravel-4

Newbie to PHP/Laravel here so please be patient.

I have a webpage that is searching based on 3 criteria for dogs , breed, sex and radius.

here is the relevant code:

search page

<div class="col-md-12 zero-pad-left zero-pad-right"> 
{{ Form::open(array('action' => array('DogsController@index'), 'class'=>'form width88', 'role'=>'search', 'method' => 'GET')) }} 
<div id="prefetch">
  {{ Form::text('search-breed', null, array('class' => 'typeahead form-group form-control', 'placeholder' => 'Search by breed here...')) }}
  {{ Form::text('sex', null, array('class' => 'form-group form-control', 'placeholder' => 'Search by sex here...')) }}
  {{ Form::text('miles', null, array('class' => 'form-group form-control', 'placeholder' => 'Search by distance here...')) }}




</div>
{{ Form::submit('Search', array('class' => 'btn btn-default search-bar-btn')) }}
{{ Form::close() }} 

ControllerPage

class DogsController extends \BaseController {

public function __construct()
{
    // call base controller constructor
    parent::__construct();

    // run auth filter before all methods on this controller except index and show
    $this->beforeFilter('auth', array('except' => array('show')));
}

/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
    if (Input::has('search')) {
        $queryString = Input::get('search');
        $dogs = Dog::where('name', 'LIKE', "%$queryString%")->orderBy('name')->paginate(5);
    }

    elseif (Input::has('search-breed')) 
    {
        $dogs = Dog::whereHas('breed', function($q)     
        {
            $queryString = Input::get('search-breed');
            $q->where('name', 'LIKE', "%$queryString%");

        })->orderBy('name')->paginate(5);

    } //end elseif

    else {
        $dogs = Dog::orderBy('name')->paginate(5);
        } //end else

    return View::make('dogs.index')->with(array('dogs' => $dogs));
} //end function index()

when i enter a search for poodle, male, within 20 miles, the url shows as follows:

http://ruff-love.dev/dogs?search-breed=poodle&sex=M&miles=20

The search currently works ok when searching for just breed.

I cant seem to figure out the syntax to add the SEX and RADIUS criteria also. it should allow for those criteria to be null and still perform the query.

any advice would be greatly apprecaited

like image 447
rommel109g Avatar asked Jul 20 '14 16:07

rommel109g


People also ask

How to multiple where condition in Laravel?

Laravel multiple where conditions - [OR]: In case you want your clauses to be joined with OR rather than AND , you could use the orWhere method: Syntax: ... ->where('column','operator','value') ->orWhere('column','operator','value') ...

How to write where condition in Laravel?

Laravel multiple where conditions - [OR]: It has to be regular where(). Syntax: ... ->where('column','operator','value') ->orWhere('column','operator','value') ...

How do I use whereBetween in laravel?

The whereBetween() method is a query builder chained alongside other Laravel query builders used to fetch data from the database. The whereBetween() method queries the database table to fetch rows of records from the database within a range of values.


2 Answers

You can use query scopes http://laravel.com/docs/eloquent#query-scopes to make it verbose and easier in your controller (or wherever you will be doing it in future) then chain them according to your needs:

// Dog model
public function scopeSearchBreed($query, $breed)
{
  $query->whereHas('breed', function ($q) use ($breed) {
    $q->where('name', 'like', "%{$breed}%");
  });
}

public function scopeWithinRadius($query, $radius)
{
  $query->where(...); // do math here
}

Then all you need is this:

public function index()
{
  $q = Dog::query();

  if (Input::has('search'))
  {
     // simple where here or another scope, whatever you like
     $q->where('name','like',Input::get('search'));
  }

  if (Input::has('search-breed'))
  {
     $q->searchBreed(Input::get('search-breed'));
  }

  if (Input::has('sex'))
  {
     $q->where('sex', Input::get('sex'));
  }

  if (Input::has('radius'))
  {
     $q->withinRadius(Input::get('radius'));
  }

  $dogs = $q->orderBy(..)->paginate(5);

  // ...
like image 158
Jarek Tkaczyk Avatar answered Sep 28 '22 22:09

Jarek Tkaczyk


Here's one possible solution, I think there are probably others. Create an empty query builder with the query() function and add the non-null clauses to it, then call the paginate() function at the end.

$builder = Dogs::query();
if (Input::has('search')) {
    $queryString = Input::get('search');
    $builder->where('name', 'LIKE', "%$queryString%");
}
// ... more clauses from the querystring
$dogs = $builder->orderBy('name')->paginate(5);
like image 29
Dave Morrissey Avatar answered Sep 28 '22 22:09

Dave Morrissey