Skip to content

Instantly share code, notes, and snippets.

@tunecino
Created November 17, 2015 14:01
Show Gist options
  • Save tunecino/abdde2b7954a7165f1d5 to your computer and use it in GitHub Desktop.
Save tunecino/abdde2b7954a7165f1d5 to your computer and use it in GitHub Desktop.
A helper function using yii\db\BaseActiveRecord::getRelation() to get relation type + optional check if both models are related on DB if respective ids are provided
<?php
private function relationInfo($model, $name, $related_id = false)
{
$relation = $model->getRelation($name, false);
if ($relation === null) return null;
$info = [];
$info['class'] = $relation->modelClass;
if ($relation->multiple === true && $relation->via === null) $info['type'] = 'is_child';
else if ($relation->multiple === true) $info['type'] = 'many_many';
else $info['type'] = 'is_parent';
$pk = implode(',', array_values($model->tableSchema->primaryKey));
$info['key'] = $info['type'] === 'is_child' ? null : $relation->link[$pk];
if ($related_id) {
if ($model->getIsNewRecord())
throw new \yii\base\InvalidCallException('Unable to check relation. model is not yet saved.');
if ($info['type'] == 'is_parent')
$info['related'] = isset($model->{$info['key']}) && $model->{$info['key']} === (int)$related_id;
if ($info['type'] == 'many_many')
$info['related'] = (new \yii\db\Query())
->from(reset($relation->via->from))
->where([ key($relation->via->link) => $model->id, $info['key'] => $related_id ])
->exists();
}
return $info;
}
// Examples :
$tag = Tag::findOne(1);
$image = Image::findOne(2);
$owner = Owner::findOne(1);
$this->relationInfo($tag, 'images', 2);
/** Output :
* {
* "class": "\app\models\Image",
* "type": "many_many",
* "key": "image_id",
* "related": true
* },
*/
$this->relationInfo($image, 'tags', 1);
/** Output :
* {
* "class": "\app\models\Tag",
* "type": "many_many",
* "key": "tag_id",
* "related": true
* },
*/
$this->relationInfo($tag, 'owner', 1);
/** Output : null, **/
$this->relationInfo($owner, 'tags', 1);
/** Output : null, **/
$this->relationInfo($image, 'owner', 1);
/** Output :
* {
* "class": "\app\models\Owner",
* "type": "is_parent",
* "key": "owner_id",
* "related": false
* },
*/
$this->relationInfo($owner, 'images', 1);
/** Output :
* {
* "class": "\app\models\Image",
* "type": "is_child",
* "key": null
* }
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment