Laravel version 9.x PHP version 8.1
Current code.
/**
* 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();
}
New business rule:
List all servers, paginated, initially bringing all servers linked to the informed site, followed by the other servers that have no relationship with the informed site or any other site. In all cases (abstinence and existence), the result must be ordered by server name.
Assume you have access to the $site
variable to perform the query.
This the part of the code that need to be updated.
$result = Server::select('id', 'name')
->orderBy('name', 'asc')
->simplePaginate(config('app.limit'));
Note:
Bringing in all the results to do the sort in PHP would not be an option. The idea is to bring the result ready with the query.
I tried using join()
and with()
but I didn't get it. I think because of my own limitation.
If anyone has a suggestion on how to do this, I would appreciate the help.
The web page: This is the site editing (location) page. On this screen, all servers available for relationship are listed, in a paginated manner. What I need is to display, at the beginning of the table listing all servers, the servers that are related to the site being edited, followed by the other servers.
Exemple: Editing Vancouver Site
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.
$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);
I asked the same question on the Laracast forum and got the answer there. User Rodrigo Pedra who replied and it's working.
I post it here to multiply knowledge.
Anyway, here's the link to the conversation.