如何获取Laravel 9.x belongsToMany关系中orderBy关系存在的记录,使用分页依次禁欲
How to get records in Laravel 9.x belongsToMany relationship orderBy relationship existence, followed by abstinence using pagination
Laravel 版本 9.x
PHP 版本 8.1
当前代码。
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Site $site
*
* @return \Illuminate\Http\Response
*/
public function edit(Request $request, Site $site)
{
$site->load(['servers' => function($query) {
$query->select('id')->orderBy('id', 'asc');
}]);
$result = Server::select('id', 'name')
->orderBy('name', 'asc')
->simplePaginate(config('app.limit'));
if ($request->ajax()) {
return response()->view('site.ajax.edit', compact('site', 'result'));
}
return response()->view('site.edit', compact('site', 'result'));
}
\ app/models/Server.php
public function sites()
{
return $this->belongsToMany(Site::class, 'server_site', 'server_id', 'site_id')->withTimestamps();
}
\ app/models/Site.php
public function servers()
{
return $this->belongsToMany(Server::class, 'server_site', 'site_id', 'server_id')->withTimestamps();
}
新业务规则:
列出所有服务器,分页,最初将所有服务器链接到通知站点,然后是与通知站点或任何其他站点没有关系的其他服务器。在所有情况下(禁欲和存在),结果必须按服务器名称排序。
假设您有权访问 $site
变量来执行查询。
这部分代码需要更新。
$result = Server::select('id', 'name')
->orderBy('name', 'asc')
->simplePaginate(config('app.limit'));
注意:
将所有结果引入 PHP 中进行排序不是一种选择。这个想法是将结果与查询一起准备好。
我尝试使用 join()
和 with()
但我没有得到它。我想是因为我自己的局限。
如果有人对如何执行此操作有建议,我将不胜感激。
网页:
这是站点编辑(位置)页面。在此屏幕上,以分页方式列出了所有可用于关系的服务器。
我需要的是在 table 列出所有服务器的开头显示与正在编辑的站点相关的服务器,然后是其他服务器。
例子:
编辑温哥华网站
All Servers
| Checkbox | Server Name |
| -------- | -------------- |
| Checked | server bbb |
| Checked | server ddd |
| Checked | server fff |
| unchecked | server aaa |
| unchecked | server ccc |
| unchecked | server ggg |
pages 1, 2, 3, 4, etc.
根据我的说法,您必须执行以下代码:
$maxServersPerPages = 20;
$page = \Request::input('page') ?? 1;
$relatedServers = $site->load('servers')->servers()->orderBy('name')->get();
$otherServers = Server::whereNotIn('id', $relatedServers->pluck('id'))->orderBy('name')->get();
$allServers = $relatedServers->merge($otherServers);
$currentPageServers = $allServers->forPage($page, $maxServersPerPage)
我们通过预先加载获取与您站点相关的所有服务器;然后我们得到所有与您的站点无关的服务器,这意味着我们必须排除我们之前在查询中得到的所有服务器;我们合并我们通过获取一个集合获得的服务器集合,最后我们根据您的 $maxServerPerPage
值获得与指定页面相关的服务器分页。
$result = Server::select('id', 'name')
->orderByDesc(
Site::selectRaw(1)
->leftJoin('server_site', 'sites.id', 'server_site.site_id')
->whereColumn('server_site.server_id', 'servers.id')
->where('server_site.site_id', $site->id)
->union(fn ($query) => $query->selectRaw(0))
->limit(1)
->toBase()
)
->orderBy('name', 'asc')
->simplePaginate($per_page);
我在 Laracast 论坛上问了同样的问题并在那里得到了答案。回复的用户 Rodrigo Pedra 正在运行。
我post在这里增长知识
无论如何,下面是对话的link。
Laravel 版本 9.x PHP 版本 8.1
当前代码。
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Site $site
*
* @return \Illuminate\Http\Response
*/
public function edit(Request $request, Site $site)
{
$site->load(['servers' => function($query) {
$query->select('id')->orderBy('id', 'asc');
}]);
$result = Server::select('id', 'name')
->orderBy('name', 'asc')
->simplePaginate(config('app.limit'));
if ($request->ajax()) {
return response()->view('site.ajax.edit', compact('site', 'result'));
}
return response()->view('site.edit', compact('site', 'result'));
}
\ app/models/Server.php
public function sites()
{
return $this->belongsToMany(Site::class, 'server_site', 'server_id', 'site_id')->withTimestamps();
}
\ app/models/Site.php
public function servers()
{
return $this->belongsToMany(Server::class, 'server_site', 'site_id', 'server_id')->withTimestamps();
}
新业务规则:
列出所有服务器,分页,最初将所有服务器链接到通知站点,然后是与通知站点或任何其他站点没有关系的其他服务器。在所有情况下(禁欲和存在),结果必须按服务器名称排序。
假设您有权访问 $site
变量来执行查询。
这部分代码需要更新。
$result = Server::select('id', 'name')
->orderBy('name', 'asc')
->simplePaginate(config('app.limit'));
注意:
将所有结果引入 PHP 中进行排序不是一种选择。这个想法是将结果与查询一起准备好。
我尝试使用 join()
和 with()
但我没有得到它。我想是因为我自己的局限。
如果有人对如何执行此操作有建议,我将不胜感激。
网页: 这是站点编辑(位置)页面。在此屏幕上,以分页方式列出了所有可用于关系的服务器。 我需要的是在 table 列出所有服务器的开头显示与正在编辑的站点相关的服务器,然后是其他服务器。
例子: 编辑温哥华网站
All Servers
| Checkbox | Server Name |
| -------- | -------------- |
| Checked | server bbb |
| Checked | server ddd |
| Checked | server fff |
| unchecked | server aaa |
| unchecked | server ccc |
| unchecked | server ggg |
pages 1, 2, 3, 4, etc.
根据我的说法,您必须执行以下代码:
$maxServersPerPages = 20;
$page = \Request::input('page') ?? 1;
$relatedServers = $site->load('servers')->servers()->orderBy('name')->get();
$otherServers = Server::whereNotIn('id', $relatedServers->pluck('id'))->orderBy('name')->get();
$allServers = $relatedServers->merge($otherServers);
$currentPageServers = $allServers->forPage($page, $maxServersPerPage)
我们通过预先加载获取与您站点相关的所有服务器;然后我们得到所有与您的站点无关的服务器,这意味着我们必须排除我们之前在查询中得到的所有服务器;我们合并我们通过获取一个集合获得的服务器集合,最后我们根据您的 $maxServerPerPage
值获得与指定页面相关的服务器分页。
$result = Server::select('id', 'name')
->orderByDesc(
Site::selectRaw(1)
->leftJoin('server_site', 'sites.id', 'server_site.site_id')
->whereColumn('server_site.server_id', 'servers.id')
->where('server_site.site_id', $site->id)
->union(fn ($query) => $query->selectRaw(0))
->limit(1)
->toBase()
)
->orderBy('name', 'asc')
->simplePaginate($per_page);
我在 Laracast 论坛上问了同样的问题并在那里得到了答案。回复的用户 Rodrigo Pedra 正在运行。
我post在这里增长知识
无论如何,下面是对话的link。