Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Active Record relation and asArray() #1402

Closed
armpogart opened this issue Dec 2, 2013 · 7 comments
Closed

Active Record relation and asArray() #1402

armpogart opened this issue Dec 2, 2013 · 7 comments
Labels
status:to be verified Needs to be reproduced and validated. type:bug Bug

Comments

@armpogart
Copy link

If we have Model extending from ActiveRecord, we can easily query data as array using ActiveQueryTrait asArray() modifier. But when we have relation, for example (through PivotTable):

class Order extends \yii\db\ActiveRecord
{
    public function getItems()
    {
        return $this->hasMany(Item::className(), ['id' => 'item_id'])
            ->viaTable('tbl_order_item', ['order_id' => 'id']);
    }
}

and now if we try to query data using lazy loading with asArray(), we won't have items at all. If we try to load related data using eager loading ->with('items') we will have error that we are using getDb() on non-object.

Any way to load ActiveRecord data as array and have related data in in associative array?

@qiangxue
Copy link
Member

qiangxue commented Dec 2, 2013

Of course you can't use lazy loading with asArray() because you would be operating on an array.
You should use eager loading in this case.

@qiangxue qiangxue closed this as completed Dec 2, 2013
@armpogart
Copy link
Author

OK, I want to use eager loading, but I get error using that approach. When I query:

$orders = Order::find()->with('items')->asArray()->all();

Without ->asArray(), everything works as expected, but why I can't load data asArray with relation?

@qiangxue
Copy link
Member

qiangxue commented Dec 2, 2013

What error did you get? What's the error call stack? How are Order and the items relation declared?

@armpogart
Copy link
Author

Here is my case:
I have 2 ActiveRecord models Driver and Car. Driver model is related to car through Pivot Table:

public function getCars()
{
    return $this->hasMany(Car::className(), ['id' => 'car_id'])
        ->viaTable('wpta_driver_car', ['driver_id' => 'id']);
}

When I load Driver model in Controller following way:

$drivers = Driver::find()->with('cars')->all();

everything loads just fine, and I can see that cars are loaded. But when I want to load drivers with their cars as array:

$drivers = Driver::find()->with('cars')->asArray()->all();

I get error: Call to a member function getDb() on a non-object in vendor\yiisoft\yii2\yii\db\ActiveRelationTrait.php at line 250. It is the following line: return $this->asArray()->all($primaryModel->getDb());.

Why I can't load related data as array. Sometimes it's crucial for applications.

@armpogart
Copy link
Author

Here is full screenshot of call stack:
h6ibtep

@armpogart
Copy link
Author

So after further investigation I've found out that there is simple fix. I've changed following function:

private function findPivotRows($primaryModels)
    {
        if (empty($primaryModels)) {
            return [];
        }
        $this->filterByModels($primaryModels);
        /** @var ActiveRecord $primaryModel */
        $primaryModel = reset($primaryModels);
        return $this->asArray()->all($primaryModel->getDb());
    }

to

private function findPivotRows($primaryModels)
    {
        if (empty($primaryModels)) {
            return [];
        }
        $this->filterByModels($primaryModels);
        /** @var ActiveRecord $primaryModel */
        $primaryModel = reset($primaryModels);
        return $this->asArray()->all();
    }

I've simply removed ->getDB() part in last line. In that case as far as I understand Yii::getDb() is used under the hood, so it may bring some problems if other than default connection was used.
This simple fix gives the exact expected result.
Sadly I can't come up with better fix without going deeper in the code, but I can do it in 2-3 days when I have some more spare time, if I can be of any help.

qiangxue added a commit that referenced this issue Dec 4, 2013
@armpogart
Copy link
Author

Thanks!!!
Your team is doing fantastic job, I've learned many new things with the help of Yii 1 and now Yii 2!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:to be verified Needs to be reproduced and validated. type:bug Bug
Projects
None yet
Development

No branches or pull requests

2 participants