/** * With method is very similar to load() one, except it will always include related data to * parent query using INNER JOIN, this method can be applied only to ORM loaders and relations * using same database as parent record. * * Method generally used to filter data based on some relation condition. * Attention, with() method WILL NOT load relation data, it will only make it accessible in * query. * * By default joined tables will be available in query based on realtion name, you can change * joined table alias using relation option "alias". * * Do not forget to set DISTINCT flag while including HAS_MANY and MANY_TO_MANY relations. In * other scenario you will not able to paginate data well. * * Examples: * * //Find all users who have comments comments * User::find()->with('comments'); * * //Find all users who have approved comments (we can use comments table alias in where * statement). * User::find()->with('comments')->where('comments.approved', true); * * //Find all users who have posts which have approved comments * User::find()->with('posts.comments')->where('posts_comments.approved', true); * * //Custom join alias for post comments relation * $user->with('posts.comments', [ * 'alias' => 'comments' * ])->where('comments.approved', true); * * //If you joining MANY_TO_MANY relation you will be able to use pivot table used as relation * name * //plus "_pivot" postfix. Let's load all users with approved tags. * $user->with('tags')->where('tags_pivot.approved', true); * * //You can also use custom alias for pivot table as well * User::find()->with('tags', [ * 'pivotAlias' => 'tags_connection' * ]) * ->where('tags_connection.approved', false); * * You can safely combine with() and load() methods. * * //Load all users with approved comments and pre-load all their comments * User::find()->with('comments')->where('comments.approved', true) * ->load('comments'); * * //You can also use custom conditions in this case, let's find all users with approved * comments * //and pre-load such approved comments * User::find()->with('comments')->where('comments.approved', true) * ->load('comments', [ * 'where' => ['{@}.approved' => true] * ]); * * //As you might notice previous construction will create 2 queries, however we can simplify * //this construction to use already joined table as source of data for relation via "using" * //keyword * User::find()->with('comments')->where('comments.approved', true) * ->load('comments', ['using' => 'comments']); * * //You will get only one query with INNER JOIN, to better understand this example let's use * //custom alias for comments in with() method. * User::find()->with('comments', ['alias' => 'commentsR'])->where('commentsR.approved', true) * ->load('comments', ['using' => 'commentsR']); * * @see load() * @param string $relation * @param array $options * @return $this */ public function with($relation, array $options = []) { if (is_array($relation)) { foreach ($relation as $name => $options) { if (is_string($options)) { //Array of relation names $this->with($options, []); } else { //Multiple relations or relation with addition load options $this->with($name, $options); } } return $this; } //Requesting primary loader to join nested relation, will only work for ORM loaders $this->loader->joiner($relation, $options); return $this; }