问题
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
回答1:
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);
// ...
回答2:
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);
回答3:
$builder = Dogs::query();
$term = Request::all();
if(!empty($term['breed'])){
$builder->where('breed','=',$term['breed']);
}
if(!empty($term['sex'])){
$builder->where('sex','=',$term['sex']);
}
if(!empty($term['radius'])){
$builder->where('radius','=',$term['radius']);
}
$result = $builder->orderBy('id')->get();
来源:https://stackoverflow.com/questions/24852704/laravel-search-query-with-multiple-conditions