检索Yii2结表数据 [英] Retrieve data from junction table in Yii2

查看:174
本文介绍了检索Yii2结表数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图获取的数据连接表中Yii2 不需要额外的查询。我有2通过接线表(USER_GROUP)相关车型(用户,组)。在USER_GROUP表,我想存储额外的数据(管理标志,...)这个关系。

  • 什么是将数据添加到结合​​表的最佳方法是什么?的联系方法接受一个参数的extraColumns,但我无法弄清楚如何工作的。

  • 什么是检索此数据的最佳方式?我写了一个额外的查询来获取值出联接表。必须有一个更清洁的方式做到这一点?!。

仅供参考,我这是怎么定义的模型之间的关系:

Group.php

 公共职能getUsers(){
    返回$这个 - >的hasMany(用户::类名(),['身份证'=>'USER_ID'])
         - > viaTable('USER_GROUP',['GROUP_ID'=>'身份证']);
}
 

user.php的

 公共职能getGroups(){
    返回$这个 - >的hasMany(集团::类名(),['身份证'=>GROUP_ID'])
         - > viaTable('USER_GROUP',['USER_ID'=>'身份证']);
}
 

解决方案

简单:使用的ActiveRecord 的结合表像你建议恕我直言,是正确的做法,因为你可以设置通过()来使用现有的的ActiveRecord 。这使您可以使用Yii中的链接()方法在路口表中创建的项目,而在同一时间将数据(如您的管理员标志)。


该负责人的Yii指南2.0状态使用接线表的方式有两种:通过() viaTable()和使用 C>(见这里)。而前者预计结表作为参数后者的名称期望的关系的名称作为参数

如果您需要访问结表里面我会使用的ActiveRecord 的结表作为你的建议,并使用通过数据()

 类用户扩展的ActiveRecord
{
    公共职能getUserGroups(){
        // 1对多
        返回$这个 - >的hasMany(用户组::类名(),['USER_ID'=>'身份证']);
    }
}

类组扩展的ActiveRecord
{
    公共职能getUserGroups(){
        // 1对多
        返回$这个 - >的hasMany(用户组::类名(),['GROUP_ID'=>'身份证']);
    }

    公共职能getUsers()
    {
        //多到很多:上面的,它使用群组关系使用了一个ActiveRecord类
        返回$这个 - >的hasMany(用户::类名(),['身份证'=>'USER_ID'])
             - >通过('群组');
    }
}

一流的用户组扩展的ActiveRecord
{
    公共职能的getUser(){
        // 1对一
        返回$这个 - > hasOne(用户::类名(),['身份证'=>'user_id说明']);
    }

    公共职能getGroup(){
        // 1对一
        返回$这个 - > hasOne(集团::类名(),['身份证'=>'userh_id']);
    }
}
 

这样,您就可以得到结表的数据,而无需使用群组的关系(如与其他任何一个一对多的关系)其他查询:

  $组=集团::找到() - >其中(['身份证'=> $ ID]) - >在('userGroups.user') -  GT ;一();
//  - > 3查询:找组,发现USER_GROUP,查找用户
// $组 - >用户组中包含联接表的数据,例如:
$ isAdmin = $组 - >群组[0]  - > adminFlag
//并且用户也取:
$ USERNAME = $组 - >群组[0]  - >用户自>的名字
 

这一切都可以使用的hasMany 的关系做了。所以,你可能会问,为什么要申报多对许多使用关系通过():因为你可以使用Yii中的链接()方法来创建在接线表中的项目:

  $用户组=新用户组();
//从表格数据装载到$用户组和验证
如果($ userGroup->负载(的Yii :: $ APP->请求 - >后期())及和放大器; $ userGroup->验证()){
    //在$用户组中的所有数据是否有效
    //  - >创建结合表包括项目。附加数据
    $组 - >链接(用户,$用户,$ userGroup-> getDirtyAttributes())
}
 

I'm trying to get data from a join table in Yii2 without an additional query. I have 2 models (User, Group) associated via the junction table (user_group). In the user_group table, I want to store extra data (admin flag, ...) for this relation.

  • What's the best way to add data to the junction table? The link method accepts a parameter extraColumns but I can't figure out how this works.

  • What's the best way to retrieve this data? I wrote an additional query to get the values out of the junction table. There must be a cleaner way to do this?!

FYI, this is how I defined the relation in the models:

Group.php

public function getUsers() {
    return $this->hasMany(User::className(), ['id' => 'user_id'])
        ->viaTable('user_group', ['group_id' => 'id']);
}

User.php

public function getGroups() {
    return $this->hasMany(Group::className(), ['id' => 'group_id'])
        ->viaTable('user_group', ['user_id' => 'id']);
}

解决方案

In short: Using an ActiveRecord for the junction table like you suggested is IMHO the right way because you can set up via() to use that existing ActiveRecord. This allows you to use Yii's link() method to create items in the junction table while adding data (like your admin flag) at the same time.


The official Yii Guide 2.0 states two ways of using a junction table: using viaTable() and using via() (see here). While the former expects the name of the junction table as parameter the latter expects a relation name as parameter.

If you need access to the data inside the junction table I would use an ActiveRecord for the junction table as you suggested and use via():

class User extends ActiveRecord
{
    public function getUserGroups() {
        // one-to-many
        return $this->hasMany(UserGroup::className(), ['user_id' => 'id']);
    }
}

class Group extends ActiveRecord
{
    public function getUserGroups() {
        // one-to-many
        return $this->hasMany(UserGroup::className(), ['group_id' => 'id']);
    }

    public function getUsers()
    {
        // many-to-many: uses userGroups relation above which uses an ActiveRecord class
        return $this->hasMany(User::className(), ['id' => 'user_id'])
            ->via('userGroups');
    }
}

class UserGroup extends ActiveRecord
{
    public function getUser() {
        // one-to-one
        return $this->hasOne(User::className(), ['id' => 'user_id']);
    }

    public function getGroup() {
        // one-to-one
        return $this->hasOne(Group::className(), ['id' => 'userh_id']);
    }
}

This way you can get the data of the junction table without additional queries using the userGroups relation (like with any other one-to-many relation):

$group = Group::find()->where(['id' => $id])->with('userGroups.user')->one();
// --> 3 queries: find group, find user_group, find user
// $group->userGroups contains data of the junction table, for example:
$isAdmin = $group->userGroups[0]->adminFlag
// and the user is also fetched:
$userName = $group->userGroups[0]->user->name

This all can be done using the hasMany relation. So you may ask why you should declare the many-to-many relation using via(): Because you can use Yii's link() method to create items in the junction table:

$userGroup = new UserGroup();
// load data from form into $userGroup and validate
if ($userGroup->load(Yii::$app->request->post()) && $userGroup->validate()) {
    // all data in $userGroup is valid
    // --> create item in junction table incl. additional data
    $group->link('users', $user, $userGroup->getDirtyAttributes())
}

这篇关于检索Yii2结表数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆