public function testActiveRelationViaTable() { /** @var Order $order */ $order = Order::findOne(1); $provider = new ActiveDataProvider(['query' => $order->getBooks()]); $items = $provider->getModels(); $this->assertEquals(2, count($items)); $this->assertTrue($items[0] instanceof Item); $this->assertTrue($items[1] instanceof Item); $provider = new ActiveDataProvider(['query' => $order->getBooks(), 'pagination' => ['pageSize' => 1]]); $items = $provider->getModels(); $this->assertEquals(1, count($items)); }
public function testValidateCompositeKeys() { $val = new UniqueValidator(['targetClass' => OrderItem::className(), 'targetAttribute' => ['order_id', 'item_id']]); // validate old record $m = OrderItem::findOne(['order_id' => 1, 'item_id' => 2]); $val->validateAttribute($m, 'order_id'); $this->assertFalse($m->hasErrors('order_id')); $m->item_id = 1; $val->validateAttribute($m, 'order_id'); $this->assertTrue($m->hasErrors('order_id')); // validate new record $m = new OrderItem(['order_id' => 1, 'item_id' => 2]); $val->validateAttribute($m, 'order_id'); $this->assertTrue($m->hasErrors('order_id')); $m = new OrderItem(['order_id' => 10, 'item_id' => 2]); $val->validateAttribute($m, 'order_id'); $this->assertFalse($m->hasErrors('order_id')); $val = new UniqueValidator(['targetClass' => OrderItem::className(), 'targetAttribute' => ['id' => 'order_id']]); // validate old record $m = Order::findOne(1); $val->validateAttribute($m, 'id'); $this->assertTrue($m->hasErrors('id')); $m = Order::findOne(1); $m->id = 2; $val->validateAttribute($m, 'id'); $this->assertTrue($m->hasErrors('id')); $m = Order::findOne(1); $m->id = 10; $val->validateAttribute($m, 'id'); $this->assertFalse($m->hasErrors('id')); $m = new Order(['id' => 1]); $val->validateAttribute($m, 'id'); $this->assertTrue($m->hasErrors('id')); $m = new Order(['id' => 10]); $val->validateAttribute($m, 'id'); $this->assertFalse($m->hasErrors('id')); }
public function testJoinWith() { // left join and eager loading $orders = Order::find()->joinWith('customer')->orderBy('customer.id DESC, order.id')->all(); $this->assertEquals(3, count($orders)); $this->assertEquals(2, $orders[0]->id); $this->assertEquals(3, $orders[1]->id); $this->assertEquals(1, $orders[2]->id); $this->assertTrue($orders[0]->isRelationPopulated('customer')); $this->assertTrue($orders[1]->isRelationPopulated('customer')); $this->assertTrue($orders[2]->isRelationPopulated('customer')); // inner join filtering and eager loading $orders = Order::find()->innerJoinWith(['customer' => function ($query) { $query->where('{{customer}}.[[id]]=2'); }])->orderBy('order.id')->all(); $this->assertEquals(2, count($orders)); $this->assertEquals(2, $orders[0]->id); $this->assertEquals(3, $orders[1]->id); $this->assertTrue($orders[0]->isRelationPopulated('customer')); $this->assertTrue($orders[1]->isRelationPopulated('customer')); // inner join filtering, eager loading, conditions on both primary and relation $orders = Order::find()->innerJoinWith(['customer' => function ($query) { $query->where(['customer.id' => 2]); }])->where(['order.id' => [1, 2]])->orderBy('order.id')->all(); $this->assertEquals(1, count($orders)); $this->assertEquals(2, $orders[0]->id); $this->assertTrue($orders[0]->isRelationPopulated('customer')); // inner join filtering without eager loading $orders = Order::find()->innerJoinWith(['customer' => function ($query) { $query->where('{{customer}}.[[id]]=2'); }], false)->orderBy('order.id')->all(); $this->assertEquals(2, count($orders)); $this->assertEquals(2, $orders[0]->id); $this->assertEquals(3, $orders[1]->id); $this->assertFalse($orders[0]->isRelationPopulated('customer')); $this->assertFalse($orders[1]->isRelationPopulated('customer')); // inner join filtering without eager loading, conditions on both primary and relation $orders = Order::find()->innerJoinWith(['customer' => function ($query) { $query->where(['customer.id' => 2]); }], false)->where(['order.id' => [1, 2]])->orderBy('order.id')->all(); $this->assertEquals(1, count($orders)); $this->assertEquals(2, $orders[0]->id); $this->assertFalse($orders[0]->isRelationPopulated('customer')); // join with via-relation $orders = Order::find()->innerJoinWith('books')->orderBy('order.id')->all(); $this->assertEquals(2, count($orders)); $this->assertEquals(1, $orders[0]->id); $this->assertEquals(3, $orders[1]->id); $this->assertTrue($orders[0]->isRelationPopulated('books')); $this->assertTrue($orders[1]->isRelationPopulated('books')); $this->assertEquals(2, count($orders[0]->books)); $this->assertEquals(1, count($orders[1]->books)); // join with sub-relation $orders = Order::find()->innerJoinWith(['items' => function ($q) { $q->orderBy('item.id'); }, 'items.category' => function ($q) { $q->where('{{category}}.[[id]] = 2'); }])->orderBy('order.id')->all(); $this->assertEquals(1, count($orders)); $this->assertTrue($orders[0]->isRelationPopulated('items')); $this->assertEquals(2, $orders[0]->id); $this->assertEquals(3, count($orders[0]->items)); $this->assertTrue($orders[0]->items[0]->isRelationPopulated('category')); $this->assertEquals(2, $orders[0]->items[0]->category->id); // join with table alias $orders = Order::find()->joinWith(['customer' => function ($q) { $q->from('customer c'); }])->orderBy('c.id DESC, order.id')->all(); $this->assertEquals(3, count($orders)); $this->assertEquals(2, $orders[0]->id); $this->assertEquals(3, $orders[1]->id); $this->assertEquals(1, $orders[2]->id); $this->assertTrue($orders[0]->isRelationPopulated('customer')); $this->assertTrue($orders[1]->isRelationPopulated('customer')); $this->assertTrue($orders[2]->isRelationPopulated('customer')); // join with ON condition $orders = Order::find()->joinWith('books2')->orderBy('order.id')->all(); $this->assertEquals(3, count($orders)); $this->assertEquals(1, $orders[0]->id); $this->assertEquals(2, $orders[1]->id); $this->assertEquals(3, $orders[2]->id); $this->assertTrue($orders[0]->isRelationPopulated('books2')); $this->assertTrue($orders[1]->isRelationPopulated('books2')); $this->assertTrue($orders[2]->isRelationPopulated('books2')); $this->assertEquals(2, count($orders[0]->books2)); $this->assertEquals(0, count($orders[1]->books2)); $this->assertEquals(1, count($orders[2]->books2)); // lazy loading with ON condition $order = Order::findOne(1); $this->assertEquals(2, count($order->books2)); $order = Order::findOne(2); $this->assertEquals(0, count($order->books2)); $order = Order::findOne(3); $this->assertEquals(1, count($order->books2)); // eager loading with ON condition $orders = Order::find()->with('books2')->all(); $this->assertEquals(3, count($orders)); $this->assertEquals(1, $orders[0]->id); $this->assertEquals(2, $orders[1]->id); $this->assertEquals(3, $orders[2]->id); $this->assertTrue($orders[0]->isRelationPopulated('books2')); $this->assertTrue($orders[1]->isRelationPopulated('books2')); $this->assertTrue($orders[2]->isRelationPopulated('books2')); $this->assertEquals(2, count($orders[0]->books2)); $this->assertEquals(0, count($orders[1]->books2)); $this->assertEquals(1, count($orders[2]->books2)); // join with count and query $query = Order::find()->joinWith('customer'); $count = $query->count(); $this->assertEquals(3, $count); $orders = $query->all(); $this->assertEquals(3, count($orders)); // https://github.com/yiisoft/yii2/issues/2880 $query = Order::findOne(1); $customer = $query->getCustomer()->joinWith(['orders' => function ($q) { $q->orderBy([]); }])->one(); $this->assertEquals(1, $customer->id); $order = Order::find()->joinWith(['items' => function ($q) { $q->from(['items' => 'item'])->orderBy('items.id'); }])->orderBy('order.id')->one(); // join with sub-relation called inside Closure $orders = Order::find()->joinWith(['items' => function ($q) { $q->orderBy('item.id'); $q->joinWith(['category' => function ($q) { $q->where('{{category}}.[[id]] = 2'); }]); }])->orderBy('order.id')->all(); $this->assertEquals(1, count($orders)); $this->assertTrue($orders[0]->isRelationPopulated('items')); $this->assertEquals(2, $orders[0]->id); $this->assertEquals(3, count($orders[0]->items)); $this->assertTrue($orders[0]->items[0]->isRelationPopulated('category')); $this->assertEquals(2, $orders[0]->items[0]->category->id); }