jostrander's avatar

Search form with Eloquent

Hello all,

I've built a very rudimentary (and poorly coded in my opinion) search form for the inventory on a project I'm working on. I'm sure there is a better way to do it, but I don't know what to search for to find any examples to do it better. Does anyone have any code critiques to make this better? I would like to add counts to each item as well, but I don't have a clue in how to do that either. Here is the code I have in my controller, which I'll eventually extract out some how:

if ($dealership = Input::get('dealership')) {
            if (Dealership::where('id',$dealership)->get()->isEmpty()) {
                //no dealership by that name. Fail silently.
            } else {
                $query->where('dealership_id',$dealership);
            }
        }
        $condition_query = clone $query;
        if ($condition = Input::get('condition')) {
            switch ($condition) {
                case 'used': $query->used(); break;
                case 'new': $query->new(); break;
            }
        }

        $year_query = clone $query;
        if ($year = Input::get('year')) {
            if (is_numeric($year))
                $query->where('year','=',$year);
        }
        $make_query = clone $query;
        if ($make = Input::get('make')) {
            if ($make != "")
                $query->where('make','LIKE', $make);
        }
        $model_query = clone $query;
        if ($model = Input::get('model')) {
            if ($model != "")
                $query->where('model','LIKE', $model);
        }
        if ($ext_color = Input::get('ext_color')) {
            if ($ext_color != "")
                $query->where('color','LIKE',$ext_color);
        }
        if ($int_color = Input::get('int_color')) {
            if ($int_color != "")
                $query->where('interior','LIKE', $int_color);
        }

        $fuel_query = clone $query;
        if ($fuel_type = Input::get('fuel_type')) {
            if ($fuel_type != "")
                $query->where('fuel_type','LIKE', $fuel_type);
        }

        $dealerships = Dealership::lists('name','id');
        $dealerships = array('0'=>'Any Location')+$dealerships;

        $fuel_options = $fuel_query->where('fuel_type','<>','')->distinct()->orderBy('fuel_type', 'ASC')->lists('fuel_type','fuel_type');
        $fuel_options = array(''=>'All Types') + $fuel_options;

        $make_options  = $make_query->where('make','<>','')->distinct()->orderBy('make', 'ASC')->lists('make','make');
        $make_options = array(''=>'All Makes') + $make_options;

        $year_options  = $year_query->orderBy('year','DESC')->distinct()->lists('year','year');
        $year_options = array(''=>'All Years') + $year_options;

        $model_options = $model_query->where('model','<>','')->orderBy('model', 'ASC')->distinct()->lists('model','model');
        $model_options = array(''=>'All Models') + $model_options;

        $vehicles = $query->remember(5)->paginate(25);

        return View::make("inventory", compact('vehicles','make_options','year_options','model_options','fuel_options','dealerships'));

Thanks for looking

0 likes
2 replies
tkjaergaard's avatar
Level 5

Wow, thats a mess :)

You could take the principles from this lesson https://laracasts.com/lessons/phpspec-and-sanitizers (See the whole lesson, but the part that you might be able to get some inspiration from starts at 16:05)

I know, it's not the same, but think in terms of extracting everything to it's own method.

an example could be:

<?php namespace Acme\Searching;

class InventorySearcher {

    public function search(array $data)
    {
        foreach ($data as $key => $value)
        {  
            $method = 'search'.ucfirst($key);

            if (method_exists($this, $method))
            {
                call_user_func([$this, $method], $value);
            }
        }
    }

    protected function searchCondition($value)
    {
        if ($value === 'used')
        {
            // do something
        }
        else
        {
            // do something else;
        }
    }

}

Optionally the search method could be extracted to a parent abstract class which might also holds the logic for creating a query.

psmail's avatar

Also check out the Laracast on search.

Please or to participate in this conversation.