Harshit Chaudhary
Harshit Chaudhary

Reputation: 442

Multiple joins behaving differently in where condition in Yii2

$materials = Material::find()
    ->where(['in', 'Material.MaterialId', $value])
    ->joinWith(['objectName'])
    ->all();

$product = Product::find()
    ->where(['Product.productId' => $id, 'Product.ModelId' => $mid])
    ->joinWith(['product' => function ($query) {
        $query->joinWith([
            'objectName',
            'contents' => function ($query2) {
                $query2->joinWith(['material' => function ($query3) {
                    $query3->where(['in', 'Material.MaterialId', $value])
                        ->joinWith(['objectName']);
                }]);
            },
        ])
        ->all();
    }])
    ->one();

I ran into an error. $query3 gives an error that IN expects two operands while if I supply the same material model it's working fine but in Product model it's not working.

Moreover I want to add products to cart products and its addons (I call them in material object). If I rewrite my $query3 as

$query3->where(['in','Material.MaterialId', ['ID1', 'ID2']])->joinWith(['objectName']);

It's working in a way it supposed to be. Also If I use ArrayHelper::toArray($value) It returns me null, Might be because the $value array is now subarray. I am sure that the $value is array.

Any suggestions?

Upvotes: 3

Views: 359

Answers (1)

topher
topher

Reputation: 14860

The variable $value does not exist within the scope of the closure it is referenced in. Each closure is a scope on its own and can only use global variables or those from its parent scope. As such $value has to be successively inherited by each closure that is a parent of the closure it is used in. This can be done via use :

$product = Product::find()
    ->where(['Product.productId' => $id, 'Product.ModelId' => $mid])
    ->joinWith(['product' => function ($query) use ($value) {
        $query->joinWith([
            'objectName',
            'contents' => function ($query2) use ($value) {
                $query2->joinWith(['material' => function ($query3) use ($value) {

The same applies for $query2 and $query3.

Upvotes: 4

Related Questions