mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 14:46:19 +08:00 
			
		
		
		
	Fixes #17089: Fixed caching of related records when via() using with callable
				
					
				
			This commit is contained in:
		
				
					committed by
					
						
						Alexander Makarov
					
				
			
			
				
	
			
			
			
						parent
						
							6aa6359bbc
						
					
				
				
					commit
					2da6773b68
				
			@ -6,7 +6,7 @@ Yii Framework 2 Change Log
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- Bug #17094: Fixed response on 204 status. Now it is empty (GHopperMSK)
 | 
					- Bug #17094: Fixed response on 204 status. Now it is empty (GHopperMSK)
 | 
				
			||||||
- Bug #17098: Fixed message/extract when using message params returned from method calls (rugabarbo)
 | 
					- Bug #17098: Fixed message/extract when using message params returned from method calls (rugabarbo)
 | 
				
			||||||
 | 
					- Bug #17089: Fixed caching of related records when `via()` using with callable (rugabarbo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2.0.16 January 30, 2019
 | 
					2.0.16 January 30, 2019
 | 
				
			||||||
-----------------------
 | 
					-----------------------
 | 
				
			||||||
 | 
				
			|||||||
@ -170,16 +170,20 @@ class ActiveQuery extends Query implements ActiveQueryInterface
 | 
				
			|||||||
            } elseif (is_array($this->via)) {
 | 
					            } elseif (is_array($this->via)) {
 | 
				
			||||||
                // via relation
 | 
					                // via relation
 | 
				
			||||||
                /* @var $viaQuery ActiveQuery */
 | 
					                /* @var $viaQuery ActiveQuery */
 | 
				
			||||||
                list($viaName, $viaQuery) = $this->via;
 | 
					                list($viaName, $viaQuery, $viaCallableUsed) = $this->via;
 | 
				
			||||||
                if ($viaQuery->multiple) {
 | 
					                if ($viaQuery->multiple) {
 | 
				
			||||||
                    if ($this->primaryModel->isRelationPopulated($viaName)) {
 | 
					                    if ($viaCallableUsed) {
 | 
				
			||||||
 | 
					                        $viaModels = $viaQuery->all();
 | 
				
			||||||
 | 
					                    } elseif ($this->primaryModel->isRelationPopulated($viaName)) {
 | 
				
			||||||
                        $viaModels = $this->primaryModel->$viaName;
 | 
					                        $viaModels = $this->primaryModel->$viaName;
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        $viaModels = $viaQuery->all();
 | 
					                        $viaModels = $viaQuery->all();
 | 
				
			||||||
                        $this->primaryModel->populateRelation($viaName, $viaModels);
 | 
					                        $this->primaryModel->populateRelation($viaName, $viaModels);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    if ($this->primaryModel->isRelationPopulated($viaName)) {
 | 
					                    if ($viaCallableUsed) {
 | 
				
			||||||
 | 
					                        $model = $viaQuery->one();
 | 
				
			||||||
 | 
					                    } elseif ($this->primaryModel->isRelationPopulated($viaName)) {
 | 
				
			||||||
                        $model = $this->primaryModel->$viaName;
 | 
					                        $model = $this->primaryModel->$viaName;
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        $model = $viaQuery->one();
 | 
					                        $model = $viaQuery->one();
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ trait ActiveRelationTrait
 | 
				
			|||||||
        if (is_object($this->via)) {
 | 
					        if (is_object($this->via)) {
 | 
				
			||||||
            $this->via = clone $this->via;
 | 
					            $this->via = clone $this->via;
 | 
				
			||||||
        } elseif (is_array($this->via)) {
 | 
					        } elseif (is_array($this->via)) {
 | 
				
			||||||
            $this->via = [$this->via[0], clone $this->via[1]];
 | 
					            $this->via = [$this->via[0], clone $this->via[1], $this->via[2]];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -105,7 +105,8 @@ trait ActiveRelationTrait
 | 
				
			|||||||
    public function via($relationName, callable $callable = null)
 | 
					    public function via($relationName, callable $callable = null)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $relation = $this->primaryModel->getRelation($relationName);
 | 
					        $relation = $this->primaryModel->getRelation($relationName);
 | 
				
			||||||
        $this->via = [$relationName, $relation];
 | 
					        $callableUsed = $callable !== null;
 | 
				
			||||||
 | 
					        $this->via = [$relationName, $relation, $callableUsed];
 | 
				
			||||||
        if ($callable !== null) {
 | 
					        if ($callable !== null) {
 | 
				
			||||||
            call_user_func($callable, $relation);
 | 
					            call_user_func($callable, $relation);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace yiiunit\data\ar;
 | 
					namespace yiiunit\data\ar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use yii\db\ActiveQuery;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class Order.
 | 
					 * Class Order.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -14,6 +16,9 @@ namespace yiiunit\data\ar;
 | 
				
			|||||||
 * @property int $customer_id
 | 
					 * @property int $customer_id
 | 
				
			||||||
 * @property int $created_at
 | 
					 * @property int $created_at
 | 
				
			||||||
 * @property string $total
 | 
					 * @property string $total
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @property-read Item[] $expensiveItemsUsingViaWithCallable
 | 
				
			||||||
 | 
					 * @property-read Item[] $cheapItemsUsingViaWithCallable
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class Order extends ActiveRecord
 | 
					class Order extends ActiveRecord
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -78,6 +83,22 @@ class Order extends ActiveRecord
 | 
				
			|||||||
            })->orderBy('item.id');
 | 
					            })->orderBy('item.id');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getExpensiveItemsUsingViaWithCallable()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasMany(Item::className(), ['id' => 'item_id'])
 | 
				
			||||||
 | 
					            ->via('orderItems', function (ActiveQuery $q) {
 | 
				
			||||||
 | 
					                $q->where(['>=', 'subtotal', 10]);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getCheapItemsUsingViaWithCallable()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->hasMany(Item::className(), ['id' => 'item_id'])
 | 
				
			||||||
 | 
					            ->via('orderItems', function (ActiveQuery $q) {
 | 
				
			||||||
 | 
					                $q->where(['<', 'subtotal', 10]);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getItemsIndexed()
 | 
					    public function getItemsIndexed()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->hasMany(Item::className(), ['id' => 'item_id'])
 | 
					        return $this->hasMany(Item::className(), ['id' => 'item_id'])
 | 
				
			||||||
 | 
				
			|||||||
@ -1275,4 +1275,22 @@ trait ActiveRecordTestTrait
 | 
				
			|||||||
        $this->assertFalse($customer->canGetProperty('non_existing_property'));
 | 
					        $this->assertFalse($customer->canGetProperty('non_existing_property'));
 | 
				
			||||||
        $this->assertFalse($customer->canSetProperty('non_existing_property'));
 | 
					        $this->assertFalse($customer->canSetProperty('non_existing_property'));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @see https://github.com/yiisoft/yii2/issues/17089
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function testViaWithCallable()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $order = Order::findOne(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $expensiveItems = $order->expensiveItemsUsingViaWithCallable;
 | 
				
			||||||
 | 
					        $cheapItems = $order->cheapItemsUsingViaWithCallable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertCount(2, $expensiveItems);
 | 
				
			||||||
 | 
					        $this->assertEquals(4, $expensiveItems[0]->id);
 | 
				
			||||||
 | 
					        $this->assertEquals(5, $expensiveItems[1]->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertCount(1, $cheapItems);
 | 
				
			||||||
 | 
					        $this->assertEquals(3, $cheapItems[0]->id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user