保存与多列的关系

时间:2014-10-23 13:00:11

标签: php mysql laravel eloquent

我有一个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));

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

编辑:对不起!我没有问正确的问题。我已经对这篇文章做了一个编辑,我已经做了 italic

1 个答案:

答案 0 :(得分:2)

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

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表之间建立关系,并依赖于使用外键进行级联删除,因此最好确保数据透视表保持尽可能干净。