Yii2:使用`joinWith()`时按数据透视表过滤查询

问题描述

采用以下示例 Cart 模型。它有一个 CartItem“枢轴记录/表”,将它链接Item

class Cart extends ActiveRecord {

    public function getCartItems() {
        return $this
            ->hasMany(CartItem::class,['cart_id' => 'id'])
            ->inverSEOf('cart');
    }

    public function getItems($callback = null) {
        return $this
            ->hasMany(Item::class,['item_id' => 'id'])
            ->via('cartItems',$callback);
    }

}

(示例 #1)此时我将能够通过 Item 的 activequery 或 CartItem查询进行过滤,如下所示:

$booksAddedToCartSinceYesterday = $cart
    ->getItems(function($cartItemQuery) {
        $cartItemQuery->andWhere('cartItem.created_at > Now()');
    })
    ->andWhere(['item.category' => 'books']);

(示例 #2)但是,当我将静态 find() 方法joinWith() 结合使用时,如何实现相同的效果?在以下示例中,我只能通过 Item 的 ActiveQuery 进行圆角分析,但我不再对 CartItem 的 ActiveQuery 对象有任何引用:

$booksAddedToCartSinceYesterday = Cart::find()
    ->andWhere(['cart.user_id' => $some_user_id])
    ->joinWith([
        'items' => function($itemQuery) {
            $itemQuery->andWhere(['item.category' => 'books']);
        },]);

如何修改上面的代码,以便能够像在示例 #1 中那样过滤 CartItem 联结表记录?如何访问联结 ActiveQuery 对象以便我可以调用 $cartItemQuery->andWhere('cartItem.created_at > Now()');

解决方法

您可以通过下面的使用关键字链接在匿名函数中传递任何变量值

在这里制作您的魔术代码以用于过滤器或任何

->joinWith([
    'items' => function($itemQuery) use ($var1,$var2){
        $itemQuery->andWhere(['item.category' => 'books']);
        $itemQuery->andWhere(['some_condition' => $var1]); <<<---------
    },]);