从数据表中搜索渴望加载的关系的访问者

时间:2018-11-20 17:18:28

标签: php laravel yajra-datatable laravel-datatables

我有以下型号:

<?php
class User extends Model {
    public function department() {
        return $this->hasOne(Department::class);
    }
}

class Department extends Model {
    protected $appends = ["email"];
    public function getEmailAttribute() {
        return "$this->name@$this->domain";
    }
    public function user() {
        return $this->belongsTo(User::class);
    }
}

我要提取用户列表,包括他们的部门,并使用服务器端分页/排序/搜索在数据表中显示此列表(使用https://stackblitz.com/edit/svg-donuts-uskvrn?file=src/app/donuts.component.ts包)

<?php
class UserController extends Controller {
    public function dt() {
        $users = User::with("department")
            ->where("location_id", session("current_location"));
        return DataTables::of($users)->make();
    }
}

在数据表设置中,我的其中一列定义如下:

{data: "department.email"}

这将显示email访问器属性,而不会出现问题。当我尝试搜索或基于此列进行排序时,就会出现问题:

  

DataTables警告:表id = DataTables_Table_0-异常消息:

     

SQLSTATE [42S22]:找不到列:1054'where子句'中的未知列'departments.email'

很显然,数据表不知道这是一个访问器,并试图将其包含在查询中–具有可预测的结果。

我能找到的唯一解决方法是使用Laravel DataTables,它允许您为特定列定义自定义WHERE子句。但据我所知, a)要求您使用查询生成器手动定义列,而 b)仅可直接在模型上使用,而不能在模型上使用关系。

是否可以使用与关系的“真实”属性相同的方法来搜索和排序此访问器属性?

3 个答案:

答案 0 :(得分:1)

因此,这就是我最终解决此问题的方法。这不是理想的解决方案,但是基本上我是用SQL重新创建访问器,手动构建查询,然后使用Datatables的filterColumn功能。

<?php
class UserController extends Controller {
    public function dt() {
        $concat = "CONCAT(departments.name, '@', departments.domain)";

        $users = User::select(["users.*", DB::raw("$concat AS dept_email")])
            ->leftJoin("departments", "users.department_id", "=", "departments.id")
            ->whereNull("departments.deleted_at")
            ->where("location_id", session("current_location"))
            ->with("departments");

        return DataTables::of($users)
            ->filterColumn(
                "dept_email",
                function($q, $k) use ($concat) {
                    return $q->whereRaw("$concat LIKE ?", ["%$k%"]);
                }
            )
            ->make();
    }
}

然后,我只将生成的列包括在表定义中,并按预期进行搜索。

答案 1 :(得分:0)

尝试将附件添加到模型。

class Department extends Model {

    protected $appends = ['email'];

    // the rest of your code
}

注意:appends数组中的属性也将遵循模型上配置的visiblehidden设置。

来源:Appending Values To JSON

答案 2 :(得分:0)