如何获取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。

https://laracasts.com/discuss/channels/laravel/belongstomany-relationship-orderby-relationship-existence-followed-by-abstinence-using-pagination?page=1&replyId=778641