php - Yii2 join relations for multiple tables -


i new yii2. have read documentation , answers on sof still cant work relations in yii2. able create raw mysql query problem dont know how create same query using yii2 relations. confused via, joinwith , key concepts. make problem descriptive possible. have 4 models.

category, categorynews, newstags, tags  category table - cat_id, cat_name news_category table - nc_id, nc_cat_id, nc_news_id news_tags table - nt_id, nt_news_id, nt_tag_id tags table - tag_id, tag_name 

what need tags model object each category, each category need news tags belonging category. request gridview. generated relations are:

category model:  public function getnewscategory() {     return $this->hasmany(newscategory::classname(), ['nc_cat_id' => 'cat_id']); }  newscategory model:  public function getncnews() {     return $this->hasone(news::classname(), ['news_id' => 'nc_news_id']); }  public function getnccat() {     return $this->hasone(category::classname(), ['cat_id' => 'nc_cat_id']); }  newstags model:  public function getntnews() {     return $this->hasone(news::classname(), ['news_id' => 'nt_news_id']); }  public function getnttag() {     return $this->hasone(tags::classname(), ['tag_id' => 'nt_tag_id']); }  news model:  public function getnewscategory() {     return $this->hasmany(newscategory::classname(), ['nc_news_id' => 'news_id']); }  public function getnewstags() {     return $this->hasmany(newstags::classname(), ['nt_news_id' => 'news_id']); }  tags model:  public function getnewstags() {     return $this->hasmany(newstags::classname(), ['nt_tag_id' => 'tag_id']); } 

ie. each category contains multiple news , each news contain mutiple tags , need tags related each category. more precisely, on gridview need categories , column displaying tags related these categories. please help!!

you can avoid declaration of models junction tables, using viatable syntax many-to-many relations. code contain 3 models (category, news , tag) , simplier.

your code ar models , relations looks follows:

public class category extends activerecord  {     public function getnews()     {         return $this->hasmany(news::classname(), ['id' => 'news_id'])             ->viatable('news_category_table', ['category_id' => 'id']);     } }  public class news extends activerecord  {     public function getcategories()     {         return $this->hasmany(category::classname(), ['id' => 'category_id'])             ->viatable('news_category_table', ['news_id' => 'id']);     }      public function gettags()     {         return $this->hasmany(tags::classname(), ['id' => 'tag_id'])             ->viatable('news_tags_table', ['news_id' => 'id']);     } }  public class tag extends activerecord  {     public function getnews()     {         return $this->hasmany(news::classname(), ['id' => 'news_id'])             ->viatable('news_tags_table', ['tag_id' => 'id']);     } } 

these relations can use in link , unlink functions (rows in junction tables managed yii in backround). keep in mind should use true second param in unlink() remove row in junction table:

$article = new news(); $tag = new tag();     $tag->save(); $article->link('tags', $tag); $article->link('caterories', $category); 

or vice versa

$tag->link('news', $article); $category->link('news', $article); 

to tags in given category can declare following function in category class:

public function gettags() {     return tags::find()         ->joinwith(['news', 'news.categories c'])         ->where(['c.id' => $this->id])         ->distinct(); } 

this work relation query , can use $category->tags or $category->gettags()->count() or other way (but not in link , unlink functions).

p.s. use provided example in code should first change names, because used singular form ar classes names (tag) , short notation primary , foreign keys (id, tag_id etc). , i'd recommend use such naming approach in code , db structure.

p.p.s. example code wasn't tested careful :)


Comments