Laravel ORM 三表关联查询(with)

2508

需要通过ORM实现子查询中的子查询,并返回正确数据

场景

  • 1.APP属于酒类外卖。
  • 2.APP内有用户的商品收藏列表,用户可以收藏每家店的商品。
  • 3.当商店下架了该商品或者删除该商品或者店铺被删除(停止合作),则商品不可见于收藏列表,数据还在。

问题

  • 1.有一家合作店铺被删除了,is_del 被置为1

  • 2.用户的收藏列表中 商品还在 ,但是点开商品进去详情报错(因为查找该商品详情的时候也判断了该店铺是否is_del = 0)

  • 3.有三个表,一个用户收藏商品表(favorite),一个商品表(goods),一个店铺表(store),关系是

  • favorite : goods_id <---------------> goods : goods_id

  • goods : store_id <--------------> store : store_id

解决方案

  • 用laravel的那个\DB::table('xxx')->leftjoin()->leftjoin()
  • 用原生拼sql,反正只是展示页,没有任何的请求参数
  • 用ORM

ORM

错误写法

大部分人一开始都这么理解,实质上,这样查询出来的结果是:如果 goods 下的 store 有则显示出来,没有则为 null,只是用来筛选 goods ,而不是来筛选 favorite

$favoriteList = Favorite::query()
            ->where('uid', $user['uid'])
            ->with([
                'goods' => function ($e) {
                    $e->where('takeaway', 1)->where('isMobileTakeaway', 200)->where('price', '>', 0)->where('state', 200)->with(['store' => function ($e) {
                        $e->where('is_del', 0);
                    }]);
                },
                'goods.goodsImport'
            ])->paginate($pageSize);

正确写法

这样才能正确的筛选favorite,实现子 子查询中的子查询

$favoriteList = Favorite::query()
            ->where('uid', $user['uid'])
            ->with([
                'goods' => function ($e) {
                    $e->where('takeaway', 1)->where('isMobileTakeaway', 200)->where('price', '>', 0)->where('state', 200);
                },
                'goods.goodsImport',
                'goods.store'
            ])->whereHas('goods.store', function ($e) {
                $e->where('is_del', 0);
            })->paginate($pageSize);