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
Make public \yii\db\ActiveQuery::populateRelations #1154
Comments
waiting for #1097 before decision on this. Can you elaborate on the use case, maybe show some code?
https://github.com/yiisoft/yii2/blob/master/docs/guide/active-record.md#lazy-and-eager-loading
When you have pagination enabled you should only load the models to be viewed so it should also only load their relations. |
Example is OTOMH, quite contrived since actual buisness logic is under NDA: class DepartmentController extends Controller {
public function actionView() {
$idDprt = Yii::$app->request->get('dprt');
$obDprt = Department::find($idDprt);
$arObJobPos = $obDprt->arObJobPos; // has relation getArJobPos()
$qJobPos = JobPosition::createQuery();
$qJobPos->populateRelations( // patched to be public by Phing
$arObJobPos,
array('obPerson')
);
// Now some daydream ..
$qJobPos->populateRelationsDeep(
$arObJobPos,
array(
'obPerson->arObNotifyChannel',
'obPerson->arObCertificate',
)
);
// And some more daydream
$qDprt = new Department::find()
->where(array('id'=>$idDprt))
->with(array(
'arObJobPos',
'arObJobPos->obPerson',
'arObJobPos->obPerson->arObNotifyChannel',
'arObJobPos->obPerson->arObCertificate',
))
;
$dpJobPos = new DeepLazyRelationActiveDataProvider(array(
'query' => $qDprt,
));
return $this->render('view',array(
'obDprt' => $obDprt,
// ...
));
}
// ...
}
Apache Cassandra disagrees, with it's broken and near non-existent |
What you want to achive should work like this: class DepartmentController extends Controller {
public function actionView() {
$idDprt = Yii::$app->request->get('dprt');
$qDprt = Department::find()
->where(array('id'=>$idDprt))
->with(array(
'arObJobPos' => function($q) {
return $q->with(['obPerson' => function($q) {
return $q->with(['arObNotifyChannel', 'arObCertificate']);
}]);
}))->one();
$dpJobPos = new DeepLazyRelationActiveDataProvider(array(
'query' => $qDprt,
));
return $this->render('view',array(
'obDprt' => $obDprt,
// ...
));
}
// ...
} |
How does the dataprovider know which records will be displayed and which not? |
Thank you very much, i will try immediately, this should go straight to documentation on relations !
if ( $this->with ) {
$obQueryDontKnowHowToCreate->populateRelations($models,$this->with);
} The custom CassandraDataProvider will maybe look like this:
|
Sounds like this is solvable when we merged #1097. You could even try to simulate orderBy in ActiveQuery class then. |
@cebe
Won't you come up with more elegant way of collecting this data ? Purpose-crafted relations with pre-made Also, what about partial views ? In this scenario, department/view.php probably has Did Yii2 architects ever think of widgetizing models, giving them So, how would you combine that assigning of view with the process of building deep query ? |
@cebe
to inroduce something like this ?
I understand that closure allows us to set any kind of addWhere etc. parameters also so it is really nice syntax @mcd-php |
I added some doc about sub-relation: bc393ff |
Great, thanks @qiangxue :) |
Is there any point open in this issue? If not, please close. |
@cebe So, what about actually make this method public ? If the array of rows is already here (no matter how it's created, maybe not simple one query), this seems to be the only way to populate relations, isn't it ? |
In case you ever encounter a case like this $qDprt = Department::find()->all()
$qDprt[0]->getRelation('arObJobPos')->findWith('arObJobPos', $dDprt); if you have only one record you can use $qDprt = Department::find(1);
$models = ...;
$qDprt->populateRelation('arObJobPos', $models); |
Done: a2fe128 |
I use it many times in controllers where array of models is fetched via object relation, not via query.
Drive-by questions (worth separate issues ?):
with()
not only JobPositions but also Persons ? If not yet, what is the best way to implement it ?The text was updated successfully, but these errors were encountered: