通过 Eloquent 访问器字段在 Yajrabox 数据表中排序

Posted

技术标签:

【中文标题】通过 Eloquent 访问器字段在 Yajrabox 数据表中排序【英文标题】:Sorting in Yajrabox datatable by Eloquent accessor field 【发布时间】:2019-10-27 14:21:51 【问题描述】:

我有一个包含 first_name 和 last_name 字段的用户表,以及一个访问器 getFullNameAttribute,我使用 Yajrabox 数据表将其显示为交互式表。我可以使用“fullName”访问器正确显示表格,但是当我尝试按此“fullName”字段进行排序时,什么都没有发生。 ajax 调用被执行,但排序保持不变并且没有报告错误。我可以按任何其他字段进行排序,并且效果很好。 此包的添加模型属性是否有排序限制?似乎在文档上找不到任何内容。

非常感谢!

【问题讨论】:

您能否也分享您的代码。 虚拟属性不能用于排序,因为它将在内存中执行。您可以在查询中构建全名并将查询包装在子查询中,然后您可以按它进行排序。 【参考方案1】:

要详细说明我的评论,这里有一个答案。

您不能使用虚拟属性(例如您想要的getFullNameAttribute())进行排序和过滤。即使它有效,它也会在内存中执行,因为这些访问器无法被 Laravel 自动转换为 SQL。

相反,您可以在 SQL 中重新创建所需的访问器。仅此还不够,因为 yajra 的 DataTables 包不能按表达式排序,只能按列名排序。因此,您必须将整个查询包装在另一个查询中。示例:

class UserDataTable extends DataTable

    public function query(): \Illuminate\Database\Query\Builder
    
        return DB::query()->fromSub(
            User::query()
                ->select([
                    '*',
                    DB::raw("CONCAT(first_name, ' ', last_name) as full_name")
                ]),
            'wrapped'
        );
    

    protected function getColumns(): array
    
        return [
            ['data' => 'first_name', 'title' => 'First Name'],
            ['data' => 'last_name', 'title' => 'Last Name'],
            ['data' => 'full_name', 'title' => 'Full Name'],
        ];
    

请注意,用DB::query()->fromSub(...) 包裹表格会阻止您在过滤器部分中使用类型提示:

public function dataTable($query): DataTableAbstract

    /** @var QueryDataTable $dataTable */
    $dataTable = datatables($query);

    return $dataTable
        ->editColumn('first_name', function ($user) 
            /** @var User|\stdClass $user */
            return ucfirst($user->first_name);
        );

使用/** @var User|\stdClass $user */ 是一种在函数参数中没有类型提示的情况下仍然获得 IDE 支持的方法。

【讨论】:

Namoshek,你是大师。非常感谢!

以上是关于通过 Eloquent 访问器字段在 Yajrabox 数据表中排序的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent ORM字段处理

如何在包含具有 Eloquent 的对象数组的 json 字段中求和

Laravel Eloquent发现并返回两种不同的类型?

Laravel Eloquent 根据数据透视表字段条件获取多对多关系

Laravel Eloquent:返回数组键作为字段 ID

仅当一个字段作为数组提供时,Laravel Eloquent 才插入多条记录