微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – Yii2连接多个表的关系

我是yii2的新手.我已经阅读了关于sof的文档和一些答案,但我仍然不能在yii2中处理关系.我能够为问题创建原始的mysql查询,但我不知道如何使用yii2关系创建相同的查询.我对via,joinWith和一些关键概念感到困惑.我会尽可能地描述问题.
我有四个型号.

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

我需要的是为每个类别标记模型对象,即对于每个类别,我需要属于该类别的所有新闻标签.请求来自gridview.
生成的关系是:

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']);
}

即.每个类别包含多个新闻,每个新闻包含多个标签,我需要与每个类别相关的所有标签.
更确切地说,在gridview上,我需要所有类别和一列显示与这些类别相关的所有标签.
请帮忙!!

解决方法:

您可以避免使用viaTable语法来声明连接表的模型,以实现多对多关系.那么你的代码将只包含三个模型(类别,新闻和标签),一切都会简单得多.

您的AR模型和关系代码可能如下所示:

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']);
    }
}

您可以在linkunlink函数中使用这些关系(联结表中的行将由Yii在backround中管理).但请记住,您应该在unlink()中使用TRUE作为第二个参数来删除联结表中的行:

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

或相反亦然

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

获取给定类别中的所有标记,您可以在Category类中声明以下函数

public function getTags()
{
    return Tags::find()
        ->joinWith(['news', 'news.categories C'])
        ->where(['C.id' => $this->id])
        ->distinct();
}

这将作为关系查询使用,您可以将其用作$category->标记或$category-> getTags() – > count()或任何其他方式(但不能用于链接和取消链接功能).

附:在代码中使用提供的示例您应该首先更改名称,因为我使用单数形式的AR类名称(Tag)和短符号的主键和外键(id,tag_id等).我建议您在代码数据库结构中使用这种命名方法.

P.P.S.这个示例代码没有经过测试,所以要小心:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐