Laravel-admin 复杂查询过滤器注意事项及一个「高级技巧」
相信 Laravel-admin 应该是社区里妇孺皆知的了,其作者 @song 可谓是居功至伟,几乎凭个人一己之力把中国 Laravel“艺术家”们的幸福程度拉升到世界级水准。
我个人从 Laravel-admin 这个产品受益颇多,只可惜 song 他自己看似收获极少,以至于好像有两三年没有再对其进行迭代更新了。咱们社区专门有一个 Dcat Admin 中文文档 ,相信明眼人一下就能看出这个 Dcat Admin 其实就是 Laravel-admin 的衍生产品。在这里惟愿 song 一切安好吧!
正文
话说我的一个基于 Laravel-admin 的项目今天遇到一个得用到 filter
复杂查询过滤器的需求。先上个图:
看着很平平无奇,实则暗藏玄机。
首先,「商家」数据比较多,是需要通过 Ajax 方式加载的 select
组件;其次「品类」是每个商家自己定义的,所以是需要根据选择的商家再加载的 multipleSelect
组件。
Laravel-admin 官方文档在 filter
选择框及复杂查询这块介绍得不多,例如 select
只说是参考 model-form
的。实际用下来会遇到问题,这就是本文标题中提到的:
注意事项
$filter->equal('shop_id', '所属商家')->ajax('api/shops')->load('shop_cates','api/shop_cates');
如果是写成上面这样,是会报错的(Call to a member function load() on null
)。但这种写法在 model-form
里就没问题。在 filter
里正确的写法是:
$filter->equal('shop_id', '所属商家')->load('shop_cates','api/shop_cates')->ajax('api/shops');
ok,注意事项说完了。希望能帮你节省一点试错的时间。下面要讲「高级技巧」了
高级技巧
上面提到的「品类」首先是「商品」的一个属性,其实它又是每个「商家」不同的。所以在数据的关联关系上均是多对多( BelongsToMany ),这里就不作代码示例了。
因此,要对「商品」的「品类」进行查询过滤,这里不得不用到复杂查询:
$filter->where(function ($query) {
$query->whereHas('shop_cates', function ($query) {
$query->where('shop_cate_id', $this->input);
});
}, '所属品类')->multipleSelect();
这时候麻烦来了:上面的 selecet
联动不生效。
查看网页源代码发现:复杂查询的 multipleSelect
没有 shop_cates
这个属性,取而代之的是一个随机字符串。那么我的挑战就是如何实现这个 select
联动。不知道社区里有没有人遇到过类似情况,反正我是头一次。官方文档自然是没有相关说明的,网上也几乎搜不到相关介绍。这也是我写这篇博文的原因,希望下次有人需要的时候能看到吧。
这里不多赘述了,直接上最终代码:
$s = $filter->equal('shop_id', '所属商家');
$f = $filter->where(function ($query) {
$query->whereHas('shop_cates', function ($query) {
$query->where('shop_cate_id', $this->input);
});
}, '所属品类');
$s->select()->load($f->getColumn(), 'api/shop_cates')->ajax('api/shops');
$f->multipleSelect();
最终的代码看着很简洁吧?但是很不容易才搞定的。这里的关键点首先是使用 getColumn()
把 multipleSelect
的实际属性给找到,其次是 $s
和 $f
的顺序及拼接。有兴趣的铁子们不妨试试,本文完。
本作品采用《CC 协议》,转载必须注明作者和本文链接