Laravel 5.5零工搜索项目:双输入搜索栏多条件查询实现需求
解决Laravel 5.5零工搜索功能的实现方案
嘿,我来帮你搞定这个搜索功能!基于你提到的三个模型,咱们一步步来实现这个支持区域/服务单条件或双条件的搜索功能。
第一步:确保模型关联正确
首先得把User和Area、Service的关联关系理清楚,这是搜索的基础:
1. User模型补充关联
class User extends Authenticatable { use Notifiable, EntrustUserTrait; protected $fillable = ['name', 'email', 'password', 'area_id']; // 假设用户表有area_id字段关联区域 // 用户属于一个区域 public function area() { return $this->belongsTo(Area::class); } // 用户和服务是多对多关系(一个零工可能提供多个服务) public function services() { return $this->belongsToMany(Service::class); } }
2. Area模型(可选补充)
class Area extends Model { // 一个区域有多个用户 public function users() { return $this->hasMany(User::class); } }
3. Service模型(可选补充)
class Service extends Model { // 一个服务被多个用户提供 public function users() { return $this->belongsToMany(User::class); } }
注意:多对多需要创建中间表
user_service,包含user_id和service_id两个字段,你可以用迁移生成这个表。
第二步:编写控制器的搜索逻辑
假设你有一个WorkerController,新建一个search方法来处理搜索请求:
use App\User; use Illuminate\Http\Request; class WorkerController extends Controller { public function search(Request $request) { // 获取搜索参数,默认空值 $areaId = $request->input('area_id'); $serviceId = $request->input('service_id'); // 构建查询 $workers = User::query(); // 如果选择了区域,添加区域匹配条件 if ($areaId) { $workers->where('area_id', $areaId); } // 如果选择了服务,添加服务匹配条件(用orWhereHas实现“或”逻辑) if ($serviceId) { // 这里要注意:如果已经有区域条件,需要用orWhereHas来实现“区域匹配 或 服务匹配” if ($areaId) { $workers->orWhereHas('services', function($query) use ($serviceId) { $query->where('services.id', $serviceId); }); } else { $workers->whereHas('services', function($query) use ($serviceId) { $query->where('services.id', $serviceId); }); } } // 获取结果(可以分页,比如paginate(10)) $workers = $workers->get(); // 传递结果到视图,同时回显搜索参数 return view('workers.search-results', compact('workers', 'areaId', 'serviceId')); } }
小技巧:如果需要更灵活的“或”逻辑,可以用
when方法简化代码,不过上面的写法更直观,适合Laravel 5.5版本。
第三步:创建搜索视图(搜索栏+结果页)
1. 搜索栏(可以放在布局页或者单独页面)
<form action="{{ route('workers.search') }}" method="GET"> <div class="form-group"> <label>选择区域</label> <select name="area_id" class="form-control"> <option value="">全部区域</option> @foreach(\App\Area::all() as $area) <option value="{{ $area->id }}" {{ old('area_id', $areaId) == $area->id ? 'selected' : '' }}> {{ $area->name }} </option> @endforeach </select> </div> <div class="form-group"> <label>选择服务</label> <select name="service_id" class="form-control"> <option value="">全部服务</option> @foreach(\App\Service::all() as $service) <option value="{{ $service->id }}" {{ old('service_id', $serviceId) == $service->id ? 'selected' : '' }}> {{ $service->name }} </option> @endforeach </select> </div> <button type="submit" class="btn btn-primary">搜索零工</button> </form>
2. 搜索结果页(resources/views/workers/search-results.blade.php)
<h3>搜索结果</h3> @if($workers->isEmpty()) <p>没有找到符合条件的零工</p> @else <ul> @foreach($workers as $worker) <li> {{ $worker->name }} - 所在区域:{{ $worker->area->name }} <br> 提供服务:{{ $worker->services->pluck('name')->implode(', ') }} </li> @endforeach </ul> @endif <!-- 可以再次显示搜索栏方便二次搜索 --> @include('workers.search-form')
第四步:配置路由
在routes/web.php中添加搜索路由:
Route::get('/workers/search', 'WorkerController@search')->name('workers.search');
测试场景
你可以测试这几种情况:
- 只选区域:返回该区域的所有零工
- 只选服务:返回提供该服务的所有零工
- 同时选区域和服务:返回该区域或提供该服务的零工(如果需要“且”的逻辑,把
orWhereHas改成whereHas即可)
内容的提问来源于stack exchange,提问作者Simus
相关产品推荐
相关产品推荐

