从数据表中搜索预加载关系的访问器
Searching an accessor of eager-loaded relation from 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);
}
}
我正在提取用户列表,包括他们的部门,并在服务器端 pagination/sorting/searching:
的数据表中显示(使用 Laravel DataTables 包)
<?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 warning: table id=DataTables_Table_0 - Exception Message:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'departments.email' in 'where clause'
显然,datatables 并不知道这是一个访问器,并试图将其包含在查询中——结果可预测。
我能找到的唯一解决方法是使用 the filterColumn
method,它允许您为特定列定义自定义 WHERE
子句。但据我所知,a) 要求您使用查询生成器手动定义列,而 b) 仅适用于模型直接,不是它的关系之一。
有什么方法可以搜索和排序此访问器 属性,就像我可以使用关系的“真实”属性一样?
尝试将访问器附加到模型。
class Department extends Model {
protected $appends = ['email'];
// the rest of your code
}
注意:appends
数组中的属性也将遵循模型上配置的 visible
和 hidden
设置。
这就是我最终解决这个问题的方法。这不是一个理想的解决方案,但基本上我在 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",
fn ($q, $k) => $q->whereRaw("$concat LIKE ?", ["%$k%"]);
)
->make();
}
}
然后我将生成的列包含在我的 table 定义中,搜索按预期工作。
我有以下型号:
<?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);
}
}
我正在提取用户列表,包括他们的部门,并在服务器端 pagination/sorting/searching:
的数据表中显示(使用 Laravel DataTables 包)<?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 warning: table id=DataTables_Table_0 - Exception Message:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'departments.email' in 'where clause'
显然,datatables 并不知道这是一个访问器,并试图将其包含在查询中——结果可预测。
我能找到的唯一解决方法是使用 the filterColumn
method,它允许您为特定列定义自定义 WHERE
子句。但据我所知,a) 要求您使用查询生成器手动定义列,而 b) 仅适用于模型直接,不是它的关系之一。
有什么方法可以搜索和排序此访问器 属性,就像我可以使用关系的“真实”属性一样?
尝试将访问器附加到模型。
class Department extends Model {
protected $appends = ['email'];
// the rest of your code
}
注意:appends
数组中的属性也将遵循模型上配置的 visible
和 hidden
设置。
这就是我最终解决这个问题的方法。这不是一个理想的解决方案,但基本上我在 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",
fn ($q, $k) => $q->whereRaw("$concat LIKE ?", ["%$k%"]);
)
->make();
}
}
然后我将生成的列包含在我的 table 定义中,搜索按预期工作。