【问题标题】:get laravel search with multi options使用多个选项获取 laravel 搜索
【发布时间】:2017-10-29 08:40:12
【问题描述】:

我使用的是 laravel 5.4,

我想通过多个选项获得我的网站搜索结果,目前我的应用中有title,category & location 字段,我想让用户通过选择这些字段中的任何一个来获得结果,例如,如果一个用户只是选择了基于位置的搜索能够得到结果而不会出现未填写其他选项等错误。

问题; 之前我只处理标题字段并且一切正常,但是当我定义其他两个选项时categories & locations 结果将不再返回,我的错误在哪里?

这是我的控制器:

public function search() {
        $q = Input::get('q');
        $ads = null;
        $categories = null;
        $locations = null;
        if($q) {
          $categories =  Category::where('name','LIKE','%'.$q.'%')
              ->paginate(2)
              ->appends('q', $q);
        }
        if($q) {
          $locations =  Location::where('name','LIKE','%'.$q.'%')
              ->paginate(2)
              ->appends('q', $q);
        }
        if($q) {
            $ads =  Ad::where('title','LIKE','%'.$q.'%')
                ->orWhere('description','LIKE','%'.$q.'%')
                ->paginate(2)
                ->appends('q', $q);
        }
        return view('search-result', compact('ads', 'categories', 'locations', 'q'));
     }

我的路线:

//search routes
Route::any('/search', 'HomeController@search');

我的看法:

@extends('layouts.view')

@section('content')

@if(isset($ads))
<h2>Search results</h2>
<table class="table table-striped">
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
        </tr>
    </thead>
    <tbody>
        @foreach($ads as $ad)
        <tr>
            <td>{{$ad->title}}</td>
            <td>{{$ad->description}}</td>
        </tr>
        @endforeach
    </tbody>
</table>
@else
no results!
@endif
@endsection

更新:

我的控制者关系:

use Illuminate\Http\Request;
use App\Events\StudentAdded;
use App\Ad;
use App\Company;
use App\Location;
use App\Category;
use Carbon\Carbon;
use Illuminate\Support\Facades\Input;

型号: 位置模型

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Location extends Model
{

  protected $fillable = [
      'name',
  ];

  public function ads(){
     return $this->hasMany(Ad::class);
  }
}

类别模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{

  protected $fillable = ['name'];

  public function ads(){
     return $this->hasMany(Ad::class);
  }

}

广告模型

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Ad extends Model
{

    protected $fillable = [
        'company_id', 'title', 'slug', 'image', 'description', 'address', 'job_title', 'salary',
    ];

    public function company(){
       return $this->belongsTo(Company::class);
    }
    public function category(){
       return $this->belongsTo(Category::class);
    }
    public function location(){
       return $this->belongsTo(Location::class);
    }
    public function employment(){
       return $this->belongsTo(Employment::class);
    }
}

更新 2:

搜索表格:

<form class="form-inline myform" action="/search" method="POST" role="search">
            {{ csrf_field() }}
            <div class="input-group" data-toggle="tooltip" data-placement="top" title="Title">
              <span class="input-group-addon" id="basic-addon1"><i class="fa fa-pencil"></i></span>
              <input name="q" type="text" class="form-control" placeholder="Title" aria-describedby="basic-addon1">
            </div>

            <label data-toggle="tooltip" data-placement="top" title="select category" class="sr-only mr-sm-2" for="inlineFormCustomSelect">Category</label>
            <select name="q" data-toggle="tooltip" data-placement="top" title="select category" class="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect">
              @foreach ($categories as $category)
              <option value="{{ $category->id }}">{{ $category->name }}</option>
              @endforeach
            </select>

            <label data-toggle="tooltip" data-placement="top" title="select City" class="sr-only mr-sm-2" for="inlineFormCustomSelect">City</label>
            <select name="q" data-toggle="tooltip" data-placement="top" title="select City" class="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect">
              @foreach ($locations as $location)
              <option value="{{ $location->id }}">{{ $location->name }}</option>
              @endforeach
            </select>

            <button type="submit" class="btn btn-primary">Submit</button>
          </form>

【问题讨论】:

  • 查看控制器时,您并没有利用关系。分享您的模特关系和搜索表单。
  • 我在您的表中找不到外键声明。广告模型中位置和类别的外键是什么。
  • 这些是数据库表中的 id。
  • @robertnicjoo 这些模型足以帮助您进行查询设计。但我们需要查看您的搜索表单和输入,它们会被发送到控制器以处理搜索逻辑。

标签: php laravel search


【解决方案1】:

由于您将搜索查询附加到分页链接,您可能应该在表单中使用GET。其次,您尝试传递具有相同名称的所有搜索输入。我更改了输入名称以使搜索更容易。我在下面显示的代码使用 3 个输入来制作查询以获取适当的广告。当提供 3 个输入中的任何一个时,它用于从数据库中获取广告。当提供超过 1 个输入时,我们将应用提供的所有条件。

查看

<form class="form-inline myform" action="/search" method="GET" role="search">
    {{ csrf_field() }}
    <div class="input-group" data-toggle="tooltip" data-placement="top" title="Title">
        <span class="input-group-addon" id="basic-addon1"><i class="fa fa-pencil"></i></span>
        <input name="title" type="text" class="form-control" placeholder="Title" aria-describedby="basic-addon1">
    </div>

    <label data-toggle="tooltip" data-placement="top" title="select category" class="sr-only mr-sm-2"
           for="inlineFormCustomSelect">Category</label>
    <select name="category" data-toggle="tooltip" data-placement="top" title="select category"
            class="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect">
            <option value="">Select category</option>
        @foreach ($categories as $category)
            <option value="{{ $category->id }}">{{ $category->name }}</option>
        @endforeach
    </select>

    <label data-toggle="tooltip" data-placement="top" title="select City" class="sr-only mr-sm-2"
           for="inlineFormCustomSelect">City</label>
    <select name="location" data-toggle="tooltip" data-placement="top" title="select City"
            class="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect">
            <option value="">Select Location</option>
        @foreach ($locations as $location)
            <option value="{{ $location->id }}">{{ $location->name }}</option>
        @endforeach
    </select>

    <button type="submit" class="btn btn-primary">Submit</button>
</form>

控制器

public function search()
{
    $searchTitle = request('title');
    $searchCategory = request('category');
    $searchLocation = request('location');

    $ads = null;

    if($searchTitle || $searchCategory || $searchLocation) {
        $ads = Ad::when($searchTitle, function ($query) use ($searchTitle) {
                return $query->where('title', 'like', "%{$searchTitle}%")
                    ->orWhere('description', 'like', "%{$searchTitle}%");
            })
            ->when($searchCategory, function ($query) use ($searchCategory) {
                return $query->whereHas('category', function ($query) use ($searchCategory) {
                    $query->where('id', $searchCategory);
                });
            })
            ->when($searchLocation, function ($query) use ($searchLocation) {
                return $query->whereHas('location', function ($query) use ($searchLocation) {
                    $query->where('id', $searchLocation);
                });
            })
            ->paginate(2)
            ->appends(request()->query());
    }

    return view('search-result', compact('ads'));
}

我不确定您是否需要搜索结果页面中的类别和位置。但是,如果您需要它们,那么您可以使用 ads 关系获取或根据输入值获取所有位置。这很简单,我认为你可以做到。

【讨论】:

  • 我现在尝试了这些代码,唯一改变的是标题搜索的工作方式与我添加位置和类别之前相同,但如果我将标题留空并尝试根据类别或位置获取结果将返回什么都没有。
  • 我认为还有另一个问题,因为我循环了所有类别和位置,它将始终选择一个选项,我如何在每个选项中添加一个空选项,以便他们仅在以下情况下才进入搜索圈他们被选中。
  • 您能否将dd(request()-&gt;all()); 添加到您的搜索方法中,并在您使用输入执行搜索时显示内容。
  • array:4 [▼ "_token" => "aeh9i36cTZIVmdyz54C4wJe1WkFhrQNhLWSy6I95" "title" => "first" "category" => "1" "location" => "1" ]
  • @robertnicjoo 问题是您传递了类别和位置 ID,但尝试使用它的名称进行搜索。我的查询基于您的控制器,但没有注意到。我已经更新了我的答案以使用 id 进行搜索。还为选择添加了默认选项。
猜你喜欢
  • 2017-09-06
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多