首页 > 解决方案 > Eloquent:附加相关记录

问题描述

2 个模型:FMType 和 Profile。FMPType 有许多 Profile 记录(一对多关系)。

class FMPType extends Model
{
    public function profiles()
    {
        return $this->hasMany(Profile::class, 'fmptype_id');
    }
}

class Profile extends Model
{
    public function fmptype() {
        return $this->belongsTo(FMPType::class);
    }
}

我需要将一些 FMPType 复制到另一个,包括相关配置文件:

public function copy(Request $request, int $fmptype)
{
    $source = FMPType::findOrFail($fmptype);

    // Double type
    $target = $source->replicate();
    $target->name = $source->name . ' (Copy)';
    $target->save();

    // Double profiles
    foreach ($source->profiles as $profile) {
        $targetProfile = $profile->replicate();

        // Associate new Profile with new FMPType
        // Attempt 1:  add - nothing happened, works silent, link remains as in source
        $target->profiles->add($targetProfile);
        // Attempt 2: associate - error, no such method
        $target->profiles()->associate($targetProfile);

        $targetProfile->save();
    }

    return somewhere;
}

在这里,我无法使用 Eloquent 方法将子配置文件与父 FMPType 关联。唯一的直接分配有效:$targetProfile->fmptype_id = $target->id,但从 Eloquent 的角度猜想这是错误的方式。

应该怎样做这样的关联?

更新 - 它是如何工作的:

public function copy(Request $request, int $fmptype)
{
    $source = FMPType::findOrFail($fmptype);

    // Double type
    $target = $source->replicate();
    $target->name = $source->name . ' (Copy)';
    $target->save();

    // Double profiles
    foreach ($source->profiles as $profile) {
        $targetProfile = $profile->replicate();

        // Associate new Profile with new FMPType
        // Save both relation and $targetProfile
        $target->profiles()->save($targetProfile);
        // This save() is not required anymore
        // $targetProfile->save();
    }

    return somewhere;
}

标签: laraveleloquentrelationship

解决方案


HasMany关系没有关联,你应该使用save(). 从我可以从您的代码复制中读取的内容是不必要的。我猜你只是想在你的$target.

foreach ($source->profiles as $profile) {
    $target->profiles()->save($targetProfile);
}

推荐阅读