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
Post a Comment