我的代码是这样的:
$totalCount = User::sum('count_fortress');
$lastVisit = User::orderBy('last_visit_fortress', 'DESC')->first('last_visit_fortress');
$topFiveUsers = User::whereNotNull(['count_fortress', 'last_visit_fortress'])
->orderBy('count_fortress', 'DESC')
->orderBy('last_visit_fortress', 'DESC')
->get(['id', 'count_fortress', 'last_visit_fortress'])
->take(5);
return response()->json([
"fortress" => [
"total_count" => $totalCount,
"last_visited" => $lastVisit->last_visit_fortress,
"users" => $topFiveUsers
]
]);
$totalCount = User::sum('count_museum');
$lastVisit = User::orderBy('last_visit_museum', 'DESC')->first('last_visit_museum');
$topFiveUsers = User::whereNotNull(['count_museum', 'last_visit_museum'])
->orderBy('count_museum', 'DESC')
->orderBy('last_visit_museum', 'DESC')
->get(['id', 'count_museum', 'last_visit_museum'])
->take(5);
return response()->json([
"museum" => [
"total_count" => $totalCount,
"last_visited" => $lastVisit->last_visit_museum,
"users" => $topFiveUsers
]
]);有没有可能在一种方法或类似于将逻辑放在存储库或服务中而不是控制器中?
发布于 2020-01-30 06:58:06
您可以在用户模型定义中使用作用域来重用查询。
public function scopeTopFiveUsers(Builder $query, string $context) {
->whereNotNull(['count_' . $context, 'last_visit_' . $context])
->orderBy('count_' . $context, 'DESC')
->orderBy('last_visit_' . $context, 'DESC')
->select(['id', 'count_' . $context, 'last_visit_' . $context])
}由于这两种解决方案之间存在关联,因此您可以在{}中巧妙地使用列名和基于字符串的访问属性。这个解决方案近乎聪明,但这是一个带有“不要重复自己”的心态的解决方案。还利用了作用域解决方案。
private function calculateResponse(string $context) {
$topFiveUsers = User::topFiveUsers($context)->take(5);
$lastVisit = User::orderBy('last_visit_' . $context, 'DESC')->first('last_visit_' . $context)->{'last_visit_' . $context};
return [
'total_count' => User::sum('count_' . $context),
'last_visited' => $lastVisit,
'users' => $topFiveUsers
]
}
public function controllerMethodOne() {
return response()->json([
"fortress" => [
$this->calculateResponse('fortress');
]
]);
}
public function controllerMethodTwo() {
return response()->json([
"museum" => [
$this->calculateResponse('museum');
]
]);
}发布于 2020-01-30 06:57:11
您可以按照前面的建议创建全局作用域,但是如果只是将其用作单个实例,那么我可能会这样做:
Route::get('user/{type?}', function ($name) {
//point to your controller
})->where('type', 'museum|fortress');然后在您的控制器中,当然可以指定您想要的名称。
function genericSharedFunction($type){
$totalCount = User::sum('count_'.$type);
$lastVisit = User::orderBy('last_visit_'.$type, 'DESC')->first('last_visit_'.$type);
$topFiveUsers = User::whereNotNull(['count_'.$type, 'last_visit_'.$type])
->orderBy('count_'.$type, 'DESC')
->orderBy('last_visit_'.$type, 'DESC')
->get(['id', 'count_'.$type, 'last_visit_'.$type])
->take(5);
$last_visit_prop = 'last_visit_'.$type;
return response()->json([
"$type" => [
"total_count" => $totalCount,
"last_visited" => $lastVisit->$last_visit_prop,
"users" => $topFiveUsers
]
]);
}https://stackoverflow.com/questions/59976387
复制相似问题