微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Laravel 8:一对多多态:将同一个孩子与不同的父母联系起来

如何解决Laravel 8:一对多多态:将同一个孩子与不同的父母联系起来

我使用了 Laravel documentation 中描述的一对多多态关系,以便能够将不同的父模型关联到一个子模型。我假设,我可以将不同的父模型分配给同一个子模型。但这不起作用。一旦我与同一个孩子的另一个父模型创建了一个新关系,旧的关系就会被替换。

示例:

ABC 是父模型,每个模型都有一个数据记录 (id=1)。

X 是具有一条数据记录 (id=1) 的子模型

我不能用常用方法做这样的事情:

A(id=1) X(id=1)

B(id=1) X(id=1)

C(id=1) X(id=1)

因为最后一个关系的创建总是覆盖前一个。在此示例中,将保留一个关系 (C(id=1) X(id=1))

我可以通过多对多的多态实现来做到这一点——但这实际上不是我想要的,因为我不希望父模型能够与子模型有多个关系。 (虽然我可以通过在相应字段的 *able 表中创建组合键来排除这种情况)

这是实际代码,它应该将一个图像分配给多个父模型(但只保留循环中的最后一个保存 - 如果我在循环末尾添加一个中断,则保存第一个):>

public function store(StoreImageRequest $request)
{
    $validated = $request->validated();

    $image = $validated['image'];
    $name = isset($validated['clientName']) ? $image->getClientOriginalName() : $validated['name'];
    $fileFormat = FileFormat::where('mimetype','=',$image->getClientMimeType())->first();

    $path = $image->store('images');

    $imageModel = Image::make(['name' => $name,'path' => $path])->fileFormat()->associate($fileFormat);
    $imageModel->save();

    $relatedModels = Image::getRelatedModels();

    foreach($relatedModels as $fqcn => $cn) {
        if(isset($validated['model'.$cn])) {
            $id = $validated['model'.$cn];
            $models[$fqcn] = call_user_func([$fqcn,'find'],[$id])->first();
            $models[$fqcn]->images()->save($imageModel);
        }
    }
}

解决方法

在我看来,您将一对多关系转向了错误的方向。

您的子模型应该实现 morphTo,而您的父模型应该实现 morphMany

a 
    id - integer
    title - string
    body - text

b
    id - integer
    title - string
    url - string

c
    id - integer
    title - string
    url - string

x
    id - integer
    body - text
    commentable_id - integer
    commentable_type - string

子模型

public class X extends Model
{
    public function commentable(): MorphTo
    {
        return $this->morphTo();
    }
}

父模型

public class A extends Model
{
    public function comments(): MorphMany
    {
        return $this->morphMany(X::class,'commentable');
    }
}

添加到关系:

$a = A::firstOrFail();
$x = X::firstOrFail();

// Attaches
$a->comments()->attach($x);

// Sync,removes the existing attached comments
$a->comments()->sync([$x]);

// Sync,but do not remove  existing
$a->comments()->sync([$x],false);
$a->comments()->syncWithoutDetaching([$x]);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。