Skip to content

Instantly share code, notes, and snippets.

@m8rge m8rge/WithoutTrait.php
Last active Jun 8, 2017

Embed
What would you like to do?
Without yii2 activerecord trait
<?php
class User extends ActiveRecord {
public function getPosts() {
return $this->hasMany(Post::className(), ['userId' => 'id']);
}
}
/**
* This one fetch all users without posts
*/
User::find()->without('posts')->all();
<?php
namespace common\ActiveRecordTrait;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
trait WithoutTrait
{
/**
* @param string $relation
* @param string $alias
* @return $this
*/
public function without($relation, $alias = '')
{
/** @var $this ActiveQuery */
$modelClass = $this->modelClass;
/** @var ActiveRecord $model */
$model = new $modelClass();
$modelClass = $model->getRelation($relation)->modelClass;
/** @var ActiveRecord $modelClass */
$tableName = $modelClass::tableName();
$this->joinWith([
$relation => function($query) use ($tableName, $alias) {
/** @var ActiveQuery $query */
$query->on = $query->where;
if ($alias) {
$query->alias($alias);
$query->on = self::injectAlias($query->on, $tableName, $alias);
}
return $query->where([($alias ? $alias : $tableName) . '.id' => null])->orderBy(null);
}
], false);
return $this;
}
/**
* Replace $tableName to $alias in $parseQuery
* @param array $parseQuery
* @param string $tableName
* @param string $alias
* @return array
*/
protected static function injectAlias($parseQuery, $tableName, $alias)
{
foreach ($parseQuery as $key => $val) {
if (is_array($val)) {
$parseQuery[$key] = self::injectAlias($val, $tableName, $alias);
}
if (is_string($key)) {
$newKey = str_replace($tableName . '.', $alias . '.', $key);
$parseQuery[$newKey] = $val;
unset($parseQuery[$key]);
}
}
return $parseQuery;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.