【问题标题】:Save relationship with multiple columns保存与多列的关系
【发布时间】:2014-10-25 06:27:29
【问题描述】:

我有一个 Laravel 应用程序,我正在将旧数据库迁移到新数据库。我对表格进行了一些更改,添加了一些新表格并删除了一些表格。我为此制作了一个迁移脚本。

我有一个用户。该用户被分配到一所学校和一个组。在我的旧数据库中,用户被分配到一所学校和一组。所以,我的用户表中有一个名为“group_id”的列和一个名为“school_id”的列。

现在,我做了一个映射表(我猜它是正确的英文单词),因为应该将用户分配到多个学校和多个组。

用户表:

ID |用户名 |密码 |更多...

学校表:

ID |姓名 |地址 |更多...

组表:

ID |姓名 |别名 |更多...

group_user table:

ID | group_id | user_id | school_user_id

user_school table:
ID | user_id | school_id

如您所见,我还将 school_user 关系的 ID 添加到映射表中,因为这样可以更轻松地在我的应用程序中使用。如果我从学校删除用户,我可以使用外键删除 group_user 关系。原因很简单:用户必须分配到一个学校,否则他不能在一个组中。

我用于保存用户的 Laravel 控制器是:

$user = new User;

$user->id = $gebruiker->id;
$user->username = $gebruiker->gebruikersnaam;
$user->password_md5 = $gebruiker->wachtwoord;
$user->firstname = $gebruiker->voornaam;
$user->prefix = $gebruiker->tussenvoegsel;
$user->lastname = $gebruiker->achternaam;
$user->phonenumber = $gebruiker->telefoonnummer;
$user->emailaddress = $gebruiker->email;
$user->gender = ($gebruiker->geslacht == 'man' ? 'male' : 'female'); 
$user->birthdate = $gebruiker->geboortedatum;

$user->save();

$user->groups()->sync(array('group_id' => $gebruiker->groep_id));
$user->schools()->sync(array($gebruiker->school_id));

我的用户模型有两种方法:

public function schools()
{
    return $this->belongsToMany('School');
}

public function groups()
{
    return $this->belongsToMany('Group');
}

我可以为学校保存关系。这很容易,因为映射表 school_user 有两列。 Laravel 为我解决了这个问题。但是,在 group_user 表中,我有三列

我试图让我的控制器像这样保存关系:

 $user->groups()->sync(array('group_id' => $gebruiker->groep_id, 'school_id' => $gebruiker->school_id));

但是,不幸的是,它不起作用。谁能告诉我该怎么做?

编辑:对不起!我没有问正确的问题。我对这篇文章进行了编辑,我将其设为斜体

【问题讨论】:

    标签: php mysql laravel eloquent


    【解决方案1】:

    定义关系时,您需要在数据透视表中指定任何其他列。所以:

    public function groups()
    {
        return $this->belongsToMany('Group')->withPivot(['id','school_user_id']);
    }
    

    请参阅文档here


    更新:

    您应该使用attachdetach,而不是sync,将您的用户与团体和学校相关联。 sync 将从中间数据透视表中删除任何不在您传递给它的数组中的模型——这意味着在您现有的代码中,$user->schools()->sync(array($gebruiker->school_id)) 将删除与用户关联的所有其他学校。这将允许用户仅与一所学校相关联。如果您要将sync 用于群组,则群组也是如此。

    因此,在您使用 $user->save() 保存用户后,您将运行:

    $user->schools()->attach($gebruiker->school_id);
    

    然后,获取刚刚添加到 school_user 数据透视表的条目的 id:

    $school_user_id = $user->schools()->wherePivot('school_id', $gebruiker->school_id)->first()->pivot->id;
    

    最后,附加用户和组,并设置 school_user id,以便您可以将其用作外键以允许级联删除:

    $user->groups()->attach($gebruiker->groep_id, array('school_user_id' => $school_user_id));
    

    更新 2: 事实证明,您可以在保存用户时使用sync 而不是attach 来更新数据透视表(事实上,应该),这么久当您将sync 的第二个属性设置为false 时。这样做会禁用sync 的分离行为,因此它只会为用户添加一个新的 school_user 连接,但不会删除他们的任何其他学校连接。

    $user->schools()->sync([$gebruiker->school_id], false);
    

    这样做的好处是它允许用户连接到多个学校,但可以防止数据透视表中相同的 school_user 组合出现重复条目​​。通常,这种完整性检查对于数据透视表来说不是什么大问题,因为detach 会清除所有重复的条目。但是,由于您将在数据透视表和 group_user 表之间建立关系,并且依赖于使用外键进行级联删除,因此最好确保数据透视表尽可能干净。

    【讨论】:

    • 请参阅上面有关附加/分离与同步的更新,并在您的group_user 表中设置school_user_id。我还在顶部编辑了belongsToMany 定义,以反映您对字段名称的编辑school_user_id
    • 嗯,我有这个错误。我不知道为什么。 SQLSTATE[23000]:完整性约束违规:1048 列 'school_user' 不能为空(SQL:插入到 group_usergroup_idschool_useruser_id)值(7061, , 26))。 school_user 中有一行。
    • 如果您使用上面的代码,请确保您的group_user 表有一个名为school_user_id 的列;如果它被称为school_user,则将其更改为上面$user->groups()->attach 语句中的那个。此外,为了调试,请检查 $school_user_id 的值以确保它正确获取添加到 school_user 表中的条目的 ID。
    • 确实是school_user,我改了。 $school_user_id 尽可能为空 :(
    • 在您的belongsToMany 定义中,您需要将数据透视表id 添加到withPivot 声明中的额外列列表中。由于数据透视表通常没有 id,因此 Eloquent 在从数据透视表中检索数据时不会自动带上它。 (当然,还要确保您的数据透视表确实有一个 id 列。)我在答案的第一部分编辑了 belongsToMany 关系的定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    相关资源
    最近更新 更多