我正在尝试为我的Laravel应用程序创建一个搜索表单。 基本上,用户可以输入一些字段(与可搜索的模型相关,如标题)并以不同的方式对其进行排序; 标题,创建日期,还有投票计数或收藏计数。最后两个是数据透视表的结果(多对多关系)。
我一直在为此苦苦挣扎,但我不知道如何进行。这是我到目前为止所拥有的:
public function search(SearchRequest $request)
{
$posts = Post::where('published', 1);
if (strlen($request->title) > 0) {
$posts->where('title', 'like', '%' . $request->title . '%');
}
switch($request->order_by) {
case 'title' : $orderBy = 'title'; break;
case 'createDate' : $orderBy = 'created_at'; break;
case 'favorites' : $orderBy = 'post_favorites.count(*)'; break;
case 'votes' : $orderBy = 'post_votes.count(*)'; break;
}
$posts->orderBy($orderBy, $request->order_by_direction);
$posts = $posts->get();
var_dump($posts);
}
为了简单起见,我将代码重写为一个典型的博客文章示例。感谢您的建议。
会试一
试,但它没有经过测试,因为没有什么可以测试的等等,所以请耐心等待,其他人可能会让它更简单,但希望它有所帮助。
public function search(SearchRequest $request)
{
if(count($request->get('title')) > 0){
$search_text = $request->get('title');
$order_by = $request->get('order_by');
$display_by = $request->get('order_by_direction');
$search_results = Post::where('title', 'like', '%' . $search_text . '%')->get();
if($display_by == 'asc') return this::orderSearchResults($search_results, $order_by);
return this::orderSearchResults($search_results, $order_by)->reverse();
} else {
//do something else here
}
}
private function orderSearchResults($search_results, $order_by)
{
switch ($order_by) {
case 'title' :
return $search_results->sortby('title');
break;
case 'createDate' :
return $search_results->sortby('created_at');
break;
case 'favorites' :
return $search_results->sortby(function($search){
return count($search['post_favorites']);
});
break;
case 'votes' :
return $search_results->sortby(function($search){
return count($search['post_votes']);
});
break;
default :
return $search_results;
break;
}
}
第二部分基于结果作为集合等返回。
我遇到过类似的情况,我必须让用户在不同的字段上提供搜索选项(搜索姓名、电子邮件、电话......等)并按帖子数量或姓名或电子邮件排序......这按预期工作。我尝试重写代码以匹配您提供的示例。
// if the user didn't fill the field, we assign default values
$searchText = $request->input('searchText') ?: null; // the terms we are looking for
$targetField = $request->input('targetField') ?: 'title'; // in which field we want to search
$orderBy = $request->input('orderBy') ?: 'id'; // field used to order the results
$order = $request->input('order') ?: 'DESC'; // order direction
// from here we start assembling our query depending on the request
$query = DB::table('posts')->select('*')->where('published', 1);
// if the user typed something in search bar, we look for those terms
$query->when($searchText, function($query) use ($searchText,$targetField) {
return $query->where($targetField,'like','%'.$searchText.'%');
});
// if the user wants to order by votes
$query->when($orderBy === 'votes', function ($query) use ($order) {
return $query->addSelect(DB::raw('(select count(post_id) from post_votes where post_votes.post_id = posts.id) AS nbvotes'))
->orderBy('nbvotes',$order));
});
// apply same logic for favorites
// if the orderBy is neither favorites or votes, by name or email for example...
$query->when($orderBy != 'favorites' && $orderBy != 'votes', function ($query) use ($orderBy,$order) {
return $query->orderBy($orderBy,$order);
});
// executing the query
$posts = $query->get();