【问题标题】:Handling many to many relationship through a pivot table通过数据透视表处理多对多关系
【发布时间】:2016-05-20 15:53:52
【问题描述】:

我之前问过一个类似的问题,但从那以后我做了很多改变,现在我有一个不同的问题。 我已将架构更改为如下所示。

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('userName')->default('');
    $table->string('userEmail')->default('');
    $table->timestamps();
});

Schema::create('user_groups', function(Blueprint $table)
{
    $table->increments('id');
    $table->string('groupName')->default('');
    $table->timestamps();
    $table->softDeletes();
});

Schema::create('users_user_groups', function(Blueprint $table)
{
    $table->increments('id');
    $table->integer('user_id')->unsigned();
    $table->integer('group_id')->unsigned();
});

Schema::table('users_user_groups', function(Blueprint $table) {
    $table->foreign('user_id')->references('id')->on('users');
    $table->foreign('group_id')->references('id')->on('user_groups');
});

本质上,一个用户可以属于多个 user_groups,而 user_groups 可以有多个用户。所以我在看多对多的关系 这就是我添加表 users_user_groups 的原因。然后我像这样为这两个设置我的模型

class User extends Model
{
    protected $table = 'users';
    protected $guarded = [];

    public function groups()
    {
        return $this->belongsToMany('App\Group', 'users_user_groups')->withPivot('user_id', 'group_id');
    }
}

class Group extends Model
{
    protected $table = 'user_groups';
    protected $guarded = [];

    public function profusionUser()
    {
        return $this->belongsToMany('App\User', 'pusers_user_groups')->withPivot('user_id', 'group_id');
    }
}

我非常有信心上述设置正确,对我来说这是有道理的。现在这个工作发生在我的 UserController 中。核心功能是这个 我试图评论它以解释正在发生的事情。

public function updateUsers()
{
    $users = Helper::returnUsersFromLdap();  //Get all users from Directory

    foreach($users as $userName => $userData) {
        $user = User::firstOrNew(['userName' => $userName]);  //Create user if needed

        foreach ($userData as $userEmail => $userDepartment) {
            $name = preg_replace('/@.*?$/', '', $userEmail);
            $user->userEmail = $userEmail;

            $userGroups = Helper::returnGroupsFromLdap($name); //Get all user_groups user is apart off

            foreach ($userGroups as $group) {
                $usGroup = new Group();  //Create the user_groups
                $usGroup->groupName = $group;
                $usGroup->save();
            }
            $user->save();
            $user->groups()->sync($userGroups);  //Link the users groups to the user
        }
    }

    return Redirect::route('users.index');
}

所以我的 user_groups 表中填充了类似的数据

+-----+------------+---------------------+---------------------+------------+
| id  | groupName  | created_at          | updated_at          | deleted_at |
+-----+------------+---------------------+---------------------+------------+
|   1 | Group 1    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   2 | Group 2    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   3 | Group 3    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   4 | Group 4    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   5 | Group 1    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   6 | Group 3    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   7 | Group 2    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   8 | Group 5    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|   9 | Group 1    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|  10 | Group 2    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|  11 | Group 1    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |
|  12 | Group 3    | 2016-05-20 15:55:34 | 2016-05-20 15:55:34 | NULL       |

现在第一个问题是,当我不确定是否需要重复组时,会在此表中重复组?如果 2 个用户在同一个 组,将在上面创建两个条目,每个用户一个。我应该以某种方式使其独一无二吗?

现在我的第二个问题是关于我的数据透视表。这样的输出是这样的

+-----+--------------------+
| id  | user_id | group_id |
+-----+--------------------+
|   1 |       1 |        0 |
|   2 |       1 |        0 |
|   3 |       1 |        0 |
|   4 |       2 |        0 |
|   5 |       2 |        0 |
|   6 |       3 |        0 |
|   7 |       3 |        0 |
|   8 |       3 |        0 |
|   9 |       3 |        0 |

因此 user_id 正在正确更新,并且次数正确。所以我知道 id 为 1 的用户分为 3 个组。 但是,由于某种原因,group_id 没有更新。

是否有任何原因没有正确更新?任何建议表示赞赏,最好获得有关 user_groups 的一些输入 表以及它是否应该包含唯一的组名。

非常感谢

【问题讨论】:

  • 你能显示表格定义的屏幕截图吗?只是为了找出它们的结构是否是你认为的那样......

标签: laravel laravel-5 laravel-5.1


【解决方案1】:

我不知道那个“丰富”表有什么用,但我认为:

Schema::create('users_user_groups', function(Blueprint $table)
{
    $table->increments('id');
    $table->integer('user_id')->unsigned();
    $table->integer('group_id')->unsigned();
});

应该是这样的:

Schema::create('users_user_groups', function(Blueprint $table)
{
    $table->increments('id');
    $table->integer('user_id')->unsigned();
    $table->integer('group_id')->unsigned();
    $table->foreign('user_id')->references('id')->on('users');
    $table->foreign('group_id')->references('id')->on('user_groups');
});

我的意思是,您必须在 users_user_groups 表中指定“外部”部分,但不知何故它最终出现在“profusion_whatever”表中。

【讨论】:

    【解决方案2】:

    如果有 2 个用户在同一个组中,则会在上面创建两个条目,每个用户一个。我应该以某种方式使其独一无二吗?

    是的,您的 user_groups 表应该有唯一的组。数据透视表的工作是维护多对多关系。

    在 user_groups 中有重复组的原因是创建组的 foreach 循环位于用户的 foreach 内。

    不要在该循环中直接插入数据库,而是在 foreach(users) 循环中构造一个包含组的数组。

    $groupsArray[] = []; //define this outside the users foreach loop
    
    //inside the users foreach loop
    foreach ($userGroups as $group) {
        if(!array_key_exists($group, $groupsArray){
             $groupsArray[$group] = true;
        }
    }
    
    //then, outside the users foreach loop:
    foreach($groupsArray as $group){
        $usGroup = new Group();  //Create the user_groups
        $usGroup->groupName = $group;
        $usGroup->save();
    }
    

    【讨论】:

      猜你喜欢
      • 2019-03-05
      • 2023-02-05
      • 2018-09-23
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多