在Laravel中更新模型关系

时间:2019-07-03 08:20:36

标签: php mysql laravel

在Laravel应用程序中,我有一个UserTeam之间的链接,其中表department中的users字段与name相关teams表中的字段。

这由给定的关系表示:

/**
 * Specify that a user belongs to only one team
 *
 * @return void
 */
public function team()
{
    return $this->belongsTo(Team::class, 'department', 'name');
}

很明显,这种方法的问题是,如果您更改团队名称,则会使用户孤立。

为纠正这一点,我尝试了以下操作:

/**
 * Update this team in the database
 * If the team name changes also update the associated users
 *
 * @param Team $team
 * @return void
 */
public function update(UpdateTeam $request, Team $team)
{
    $data = $request->validated();

    if ($data['name'] != $team->name) {
        foreach ($team->users as $user) {

            $user->fill([
                'department' => $data['name'],
            ])->save();
        }
    }

    $team->fill($data)->save();
}

但是在User模型中,我也有此访问器:

/**
 * Get a direct link to this user's profile using the global route helper
 */
public function getProfilePageAttribute()
{
    return $this->department ? route('profile.show', [$this->team->slug, $this->username]) : null;
}

在更新团队名称时,这会引发错误,因为在更改期间$this->team实际上是null

我有一个TeamObserver,并试图将此行为与updating事件挂钩,但是$team->users的关系也会返回null,因为它将使用当前属性,并且不是旧的属性。

在没有将团队名称映射到用户表中的ID的情况下,是否可以解决此问题?主要是由于提供的数据将名称用作部门。

是否可以告诉关系在更新时使用旧属性?

1 个答案:

答案 0 :(得分:1)

在您的模式中,通过tableColumns = ['HEADER1', 'HEADER2', 'HEADER3', 'HEADER4']; (也许还有ON UPDATE CASCADE?)在两个表之间添加外键约束,这样可以确保用户部门的名称始终与父项(部门名称)相同。

对于用户表的架构(迁移),添加外键

ON DELETE SET NULL

请记住,被引用的两个列($table->foreign('department') ->references('name') ->on('teams') ->onUpdate('cascade') // ->onDelete('set null'); users.department)必须具有完全相同的类型和长度。数据也必须不匹配(这意味着用户不能成为teams.name中不存在的部门的成员)。

如果要将其添加到新的迁移中,则可以这样做!

teams