如何在LaravelEloquent中对查询结果进行排序
在本系列的 上一部分 中,您学习了如何在 Eloquent 模型中使用 all() 方法获取数据库记录。 您可能还记得使用了一种称为 sortDesc() 的方法,该方法用于按降序对记录进行排序。
sortDesc() 方法是 Collection 类的一部分,它是一个强大的 Laravel 实用程序类,可作为原生 PHP 数组的改进版本。 此方法不会在数据库查询本身中对结果进行排序,而是反转集合的顺序,以便最后一个项目首先出现在集合中。 虽然这适用于较小的结果集,但它没有提供与在数据库查询本身中对结果进行排序相同的灵活性。
要对数据库查询中的结果进行排序,您需要使用 orderBy() 方法,并提供要用作排序条件的表字段。 这将使您更灵活地构建查询,该查询将仅从数据库中获取您需要的结果。
您现在将更改 routes/web.php 文件中的代码,以根据 created_at 表字段显示从最新到最旧的结果。
当您在表迁移中包含 timestamps() 定义时,created_at 和 updated_at 字段都由 Eloquent 管理。 您不应手动更新这些字段,但可以使用它们对查询进行排序和过滤。
在代码编辑器中打开此文件:
routes/web.php
这是代码现在的样子:
路线/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
$links = Link::all()->sortDesc();
return view('index', [
'links' => $links,
'lists' => LinkList::all()
]);
});
Route::get('/{slug}', function ($slug) {
$list = LinkList::where('slug', $slug)->first();
if (!$list) {
abort(404);
}
return view('index', [
'list' => $list,
'links' => $list->links,
'lists' => LinkList::all()
]);
})->name('link-list');
注意 /{slug} 路由,它负责按 slug 列出链接,目前没有使用任何排序方法。 链接是通过 list 变量获得的,在代码中突出显示,使用 LinkList 模型中定义的关系。
如果您现在将多个链接添加到列表中,默认情况下查询将返回从最旧到最新排序的结果。 尽管您可以使用 sortDesc() 方法在 $list->links 调用中重新排序集合,但使用 orderBy() 方法提供了更大的灵活性,并允许您在以后包含其他过滤条件。 您可以将此方法与 where() 调用链接以获得更细粒度的结果。
将前面代码示例中突出显示的行替换为以下行:
路线/web.php
'links' => $list->links()->orderBy('created_at', 'desc')->get(),
请注意,这次我们通过调用 $list->links() 方法来调用内置查询构建器,该方法引用 LinkList 类中定义的关系方法。 这与将 $list->links 作为类属性(不带括号)调用不同,后者将调用模型中的魔术方法来获取与该列表相关的所有链接。
这是完成后完整的 routes/web.php 文件的样子:
路线/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
$links = Link::all()->sortDesc();
return view('index', [
'links' => $links,
'lists' => LinkList::all()
]);
});
Route::get('/{slug}', function ($slug) {
$list = LinkList::where('slug', $slug)->first();
if (!$list) {
abort(404);
}
return view('index', [
'list' => $list,
'links' => $list->links()->orderBy('created_at', 'desc')->get(),
'lists' => LinkList::all()
]);
})->name('link-list');
保存并关闭文件。 现在,使用 link:new Artisan 命令添加几个新链接。 您可以使用默认列表:
docker-compose exec app php artisan link:new
Output Link URL: > https://laravel.com/docs/8.x/eloquent Link Description: > Laravel Eloquent Docs Link List (leave blank to use default): > New Link: https://laravel.com/docs/8.x/eloquent - Laravel Eloquent Docs Listed in: default Is this information correct? (yes/no) [no]: > yes Saved.
如果您重新加载默认链接列表页面,您现在应该获得从最新到最旧的链接:
http://localhost:8000/default
同样,如果您希望按链接描述的字母顺序对链接进行排序,则必须更改该行以在方法调用中使用该表字段,如下所示:
'links' => $list->links()->orderBy('description', 'asc')->get(),
以下是此类更改后链接的排序方式:
在本系列的下一部分中,您将学习如何从 Laravel Eloquent 查询中获取总结果数。