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