laravel 背包 ajax FetchOperation - 递归搜索 parents
laravel backpack ajax FetchOperation - search by all parents recursively
在我的模型上 AdGroup.php 我有:
public function parent() {
return $this->belongsTo(AdGroup::class);
}
public function children() {
return $this->hasMany(AdGroup::class, 'parent_id');
}
public function getTreeTitleAttribute() {
$treeTitle = $this->title;
if($this->parent) {
$treeTitle = $this->parent->getTreeTitleAttribute() . ' > ' . $treeTitle;
}
return $treeTitle;
}
$model->treeTitle returns 我是 AdGoup 的完整标题,例如:水果 > 红色水果 > 草莓
在 AdGroupCrudController.php 我有:
protected function setupCreateOperation()
{
CRUD::setValidation(AdGroupRequest::class);
$this->crud->addField([
'label' => __('admin.parent'),
'type' => 'relationship',
'name' => 'parent_id',
'entity' => 'parent',
'attribute' => 'tree_title',
'ajax' => true,
'minimum_input_length' => 0,
'allows_null' => true
]);
}
public function fetchParent()
{
return $this->fetch([
'model' => \App\Models\AdGroup::class,
'query' => function($model) {
return $model->orderBy('lft')->orderBy('id', 'ASC');
}
]);
}
这向我展示了一个 select2 下拉菜单,可以搜索所有类别并显示它们的树标题。只有一个缺点 - 搜索无法正常工作。它按标题(数据库列)而不是我在模型中定义的 treeTitle 属性进行搜索。我知道这是因为 fetchParent 方法直接从 DB 搜索,然后才在返回的结果中收到我的 treeTitle,但这也许可以解决?我在 Laravel 背包文档上找到了一个扩展的获取方法:
public function fetchUser() {
return $this->fetch([
'model' => User::class,
'query' => function($model) {
$search = request()->input('q') ?? false;
if ($search) {
return $model->whereRaw('CONCAT(`first_name`," ",`last_name`) LIKE "%' . $search . '%"');
}else{
return $model;
}
},
'searchable_attributes' => []
]);
}
也许可以扩展它以满足我的需要?当我搜索背包数据表(列表)时仍然存在同样的问题。
确实,您已经正确地指出了根本问题:
I understand that this is because fetchParent method searches directly from DB and only then, on returned results I receive my treeTitle;
以及解决方案:您可以使用 Fetch 的 query
属性自定义查询,并包含您的 treeTitle。唯一的问题是...那么您必须在 SQL 中进行 tree_title
计算...。这并不容易。
或者,不要使用 relationship
字段和 Fetch
操作。相反,您可以使用 the select2_from_ajax
field,它提供了更多的自定义空间。
因为您创建自己的路由和 CrudController 来响应 AJAX 请求,所以在该控制器中您可以
- 手动搜索搜索词
- 只保留 10 个结果
- 然后只对这 10 个结果进行 PHP 处理
example in the docs 将提供一个很好的起点。
请注意 会有 一个缺点:人们将无法搜索 Fruits > Red Fruits
,他们只能搜索 [=16] =] 或 Red Fruits
(一次一个)。但这可能是一个值得的妥协:这样做可以让您不必编写非常复杂的 SQL 查询 and/or 存储函数。
在我的模型上 AdGroup.php 我有:
public function parent() {
return $this->belongsTo(AdGroup::class);
}
public function children() {
return $this->hasMany(AdGroup::class, 'parent_id');
}
public function getTreeTitleAttribute() {
$treeTitle = $this->title;
if($this->parent) {
$treeTitle = $this->parent->getTreeTitleAttribute() . ' > ' . $treeTitle;
}
return $treeTitle;
}
$model->treeTitle returns 我是 AdGoup 的完整标题,例如:水果 > 红色水果 > 草莓
在 AdGroupCrudController.php 我有:
protected function setupCreateOperation()
{
CRUD::setValidation(AdGroupRequest::class);
$this->crud->addField([
'label' => __('admin.parent'),
'type' => 'relationship',
'name' => 'parent_id',
'entity' => 'parent',
'attribute' => 'tree_title',
'ajax' => true,
'minimum_input_length' => 0,
'allows_null' => true
]);
}
public function fetchParent()
{
return $this->fetch([
'model' => \App\Models\AdGroup::class,
'query' => function($model) {
return $model->orderBy('lft')->orderBy('id', 'ASC');
}
]);
}
这向我展示了一个 select2 下拉菜单,可以搜索所有类别并显示它们的树标题。只有一个缺点 - 搜索无法正常工作。它按标题(数据库列)而不是我在模型中定义的 treeTitle 属性进行搜索。我知道这是因为 fetchParent 方法直接从 DB 搜索,然后才在返回的结果中收到我的 treeTitle,但这也许可以解决?我在 Laravel 背包文档上找到了一个扩展的获取方法:
public function fetchUser() {
return $this->fetch([
'model' => User::class,
'query' => function($model) {
$search = request()->input('q') ?? false;
if ($search) {
return $model->whereRaw('CONCAT(`first_name`," ",`last_name`) LIKE "%' . $search . '%"');
}else{
return $model;
}
},
'searchable_attributes' => []
]);
}
也许可以扩展它以满足我的需要?当我搜索背包数据表(列表)时仍然存在同样的问题。
确实,您已经正确地指出了根本问题:
I understand that this is because fetchParent method searches directly from DB and only then, on returned results I receive my treeTitle;
以及解决方案:您可以使用 Fetch 的 query
属性自定义查询,并包含您的 treeTitle。唯一的问题是...那么您必须在 SQL 中进行 tree_title
计算...。这并不容易。
或者,不要使用 relationship
字段和 Fetch
操作。相反,您可以使用 the select2_from_ajax
field,它提供了更多的自定义空间。
因为您创建自己的路由和 CrudController 来响应 AJAX 请求,所以在该控制器中您可以
- 手动搜索搜索词
- 只保留 10 个结果
- 然后只对这 10 个结果进行 PHP 处理
example in the docs 将提供一个很好的起点。
请注意 会有 一个缺点:人们将无法搜索 Fruits > Red Fruits
,他们只能搜索 [=16] =] 或 Red Fruits
(一次一个)。但这可能是一个值得的妥协:这样做可以让您不必编写非常复杂的 SQL 查询 and/or 存储函数。