[英]Laravel How to get multi different results by executing only one query
[英]How can I get results of one search query filter only in Laravel
我正在创建一个房地产项目,该项目将为具有不同搜索过滤器的不同页面提供搜索选项。
这是搜索视图的一个示例
<form class="form-row basic-select-wrapper" method="POST" action="{{route('filter')}}">
@csrf
{{-- <div class="form-group">
<input type="text" name="prop_name">
</div> --}}
<div class="form-group col-lg col-md-6">
<label>Property type</label>
<select name="type_id" class="form-control basic-select">
<option>Select Type</option>
@foreach ($types as $type)
@if ($type->status == 1)
<option value="{{ $type->id }}">{{ $type->name }}</option>
@endif
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Property Category</label>
<select name="cat_id" class="form-control basic-select">
<option>Select Category</option>
@foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Location</label>
<select name="loc_id" class="form-control basic-select">
<option>Select Location</option>
@foreach ($locations as $location)
<option value="{{ $location->id }}">{{ $location->loc_name }}</option>
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Budget</label>
<select name="start_price" class="form-control basic-select">
<option>Select Budget</option>
@foreach($price['price'] as $key => $val)
<option value="{{$key}}">{{$val}}</option>
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Bedroom(s)</label>
<select name="min_bed" class="form-control basic-select">
<option>Select Bedroom</option>
<option value="0">studio</option>
<option value="1">one bedroom</option>
<option value="2">two bedroom</option>
<option value="3">three bedroom</option>
<option value="4">four bedroom</option>
<option value="5">five bedroom</option>
<option value="6">six bedroom</option>
<option value="7">seven bedroom</option>
</select>
</div>
<div class="advanced-search" id="advanced-search">
<div class="card card-body">
<div class="form-group col-md-12">
<div class="mt-0">
<button class="btn btn-primary align-items-center" type="submit"><i
class="fas fa-search mr-1"></i><span>Search</span></button>
</div>
</div>
</div>
</div>
</form>
这是我的搜索 controller
<?php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
//use App\Models\Listing;
use App\ListingSearch\ListingSearch;
class SearchController extends Controller
{
public function filter(Request $request)
{
return ListingSearch::apply($request);
}
}
现在,要实现这一点,因为有多个搜索过滤器,我想简化它。 这里是文件夹结构文件夹结构
这是列表搜索 Class
<?php
namespace App\ListingSearch;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Listing;
use Illuminate\Http\Request;
class ListingSearch
{
public static function apply(Request $filters)
{
$query = static::applyDecoratorsFromRequest(
$filters, (new Listing)->newQuery()
);
// Get the results and return them.
return static::getResults($query);
}
private static function applyDecoratorsFromRequest(Request $request, Builder $query)
{
foreach ($request->all() as $filterName => $value) {
$decorator = static::createFilterDecorator($filterName);
if (static::isValidDecorator($decorator)) {
$query = $decorator::apply($query, $value);
}
}
return $query;
}
private static function createFilterDecorator($name)
{
return __NAMESPACE__ . '\\Filters\\' .
str_replace(' ', '',
ucwords(str_replace('_', ' ', $name)));
}
private static function isValidDecorator($decorator)
{
return class_exists($decorator);
}
private static function getResults(Builder $query)
{
return $query->get();
}
}
这是类别的过滤器 CATID 之一的示例
<?php
namespace App\ListingSearch\Filters;
use Illuminate\Database\Eloquent\Builder;
class CatId implements Filter
{
public static function apply($builder, $value)
{
return $builder->where('cat_id', $value);
}
}
这样做的问题是我必须输入所有必需的过滤器才能获得结果,否则如果我只填写一个过滤器,我会得到 null 结果,例如我只想要公寓,而不输入位置或类别。 我怎样才能做到这一点?
您是否尝试在将 $value 堆叠到您的位置之前对其进行过滤?
if (!empty($value)) {
}
empty() 将负责过滤掉空值和 null 值。 因此,您最终会添加实际存在的查询过滤器值。
编辑
foreach ($request->all() as $filterName => $value) {
if (!empty($value)) {
$decorator = static::createFilterDecorator($filterName);
if (static::isValidDecorator($decorator)) {
$query = $decorator::apply($query, $value);
}
}
}
编辑 2
您的选项标签没有定义值属性,并且在发布到 controller 时它不为空,因为浏览器默认为标签内的值(选择类型,Select 类别等)。 您需要将 value 属性提供为空,以便 POST 不使用这样的内部文本:
<option value="">Select Type</option>
[...]
<option value="">Select Category</option>
[...]
<option value="">Select Location</option>
[...]
<option value="">Select Budget</option>
然后 if (!empty($value)) {} 可以做到这一点
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.