通过雄辩的访问者字段对Yajrabox数据表进行排序

时间:2019-06-13 03:12:25

标签: laravel eloquent datatables

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

非常感谢!

1 个答案:

答案 0 :(得分:0)

要详细说明我的评论,请在此处给出答案。

您不能使用虚拟属性(例如,所需的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支持而无需在函数参数中键入提示的一种方法。