gpt4 book ai didi

Laravel 多态多对多关系数据透视表与另一个模型的关系

转载 作者:行者123 更新时间:2023-12-04 14:55:38 25 4
gpt4 key购买 nike

我有以下表结构,如图所示:
database diagram
简而言之,它由几个多对多的多态关系组成,如下所述:

  • 许多 resources可以有很多sources和数据透视表 sourceables包含 catalog_numberlot_number信息以使数据透视表中的每一行都是唯一的。许多资源也可能来自同一来源或不同来源,由数据透视表上的目录号和批号区分。
  • 许多 resources也可以有很多publications附在它上面,通过 publicationables表带 notes在数据透视表上
  • 许多出版物也可以描述资源的来源。

  • 我的问题:
  • 由于资源的来源由数据透视表 sourceables 区分我应该如何保存 sourceables 的枢轴行之间的关系到 publications ?
  • 你能在 sourceables 之间有一个自定义的中间表模型吗?和“出版物”链接到 publications ?
  • 如何检索资源及其所有出版物以及所有相应出版物的来源?
  • 最佳答案

    这是我的答案,我希望我能为您的问题带来一些启示。我已经发布了 GitHub repository以我在这里编写的所有代码为例。我添加了有关如何在那里复制我的场景的更多信息。
    数据库和关系
    这是我对数据库及其关系的解释。您可以检查存储库上的所有迁移。
    image
    解决方案
    问题 1:
    我应该如何保存可发布的数据透视行之间的关系?
    回答:
    在继续代码示例之前,我想解释一些需要理解的重要概念。我将使用表达式 标签 引用标识符 索引用于关联模型的变形关系。
    它的工作方式是将标签分配给您想要添加到关系中的任何模型。任何使用这些标签的模型都可以存储在 Morph Pivot Table 中。 Laravel 使用 _"modelable"类型列来过滤对存储模型名称的关系的调用。您可以使用 Relation 来“标记”您的模型,在模型中创建一个方法,该方法返回 morphToMany 关系函数。
    对于这种特定情况,以下是继续操作的方法:
    在您的资源模型中,您有两种方法,一种与可来源索引相关,另一种与使用 morphToMany 作为返回的可发布标签有关。
    以下是资源模型 (./app/Models/Resource.php) 的外观:

    <?php
    namespace App\Models;

    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;

    class Resource extends Model
    {
    use HasFactory;
    protected $guarded = [];

    public function publications()
    {
    return $this->morphToMany(Publication::class, 'publicationable')->withPivot('notes');
    }

    public function sources()
    {
    return $this->morphToMany(Source::class, 'sourceable')->withPivot(['catalog_number', 'lot_number']);
    }
    }
    在您的发布模型中,您有两种方法,一种与可来源索引相关,另一种与使用 morphedByMany 的可发布标签的资源方法成反比关系。
    以下是发布模型 (./app/Models/Publication.php) 的外观:
    <?php

    namespace App\Models;

    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;

    class Publication extends Model
    {
    use HasFactory;
    protected $guarded = [];

    public function sources()
    {
    return $this->morphToMany(Source::class, 'sourceable')->withPivot(['catalog_number', 'lot_number']);
    }

    public function resources()
    {
    return $this->morphedByMany(Resource::class, 'publicationable');
    }
    }
    With this, you can be able to accomplish your goal of relating Publications with Resources and Sources.
    问题 2:您能否在 sourceable 和publishable 之间有一个中间表来链接到出版物?
    回答:
    不,你不需要。您可以使用 sourceables 表来完成此操作。通过创建返回与 Source 模型的 morphToMany 关系的方法,您始终可以将 Source 与任何模型相关联。这些我们对 上的出版物所做的工作问题 1 .
    问题 3:如何检索资源及其所有出版物以及所有相应出版物的来源?
    回答:
    我认为 Eloquent 是我在整个 Laravel 框架中最喜欢的功能。这是我们在模型定义上所做的一切。
    如果您再次检查资源和发布模型定义,我们会添加一个 withPivot() 方法,其中包含我们希望在对与 eloquent 的关系进行的任何调用中包含的相关字段。这种方法可以从数据透视表中读取自定义值。
    重要提示:对于此示例,我隐式添加了枢轴值,因为我没有在迁移时将这些列声明为 NULL。
    要使用关系将发布与资源相关联(存储在数据透视表上),您只需:
    (使用 工匠修补匠 )
    Psy Shell v0.10.8 (PHP 8.0.6 — CLI) by Justin Hileman
    >>> $publication = \App\Models\Publication::find(5)
    >>> $resource = \App\Models\Resource::find(19)
    >>> $resource->publications()->attach($publication, ["notes" => "Eureka!"]);
    ### Adding another Publication
    >>> $publication = \App\Models\Publication::find(10)
    >>> $resource->publications()->attach($publication, ["notes" => "Eureka 2!"]);
    (使用 Controller )
    use App\Models\Resource;
    use App\Models\Publication;
    ...
    $id_resource = 1; // This is the Resource Id you want to reach.
    $id_publication = 10; // This is the Resource Id you want to reach.

    $resource = Resource::find($id_resource);
    $publication = Publication::find($id_publication);
    $pivotData = [ "notes" => "Eureka!" ];

    $resource->publications()->attach($publication, $pivotData);
    要从资源中检索所有出版物,您只需:
    (使用 工匠修补匠 )
    Psy Shell v0.10.8 (PHP 8.0.6 — CLI) by Justin Hileman
    >>> $resource = \App\Models\Publication::find(5)
    >>> $resource->publications()->get();
    容易吧? :) Eloquent 力量!
    (使用 Controller )
    use App\Models\Resource;
    ...
    $id_resource = 1; // This is the Resource Id you want to reach.
    $resource = Resource::find($id_resource);

    $resource->publications()->get();
    以防万一,您可以通过以下方式存储和检索所有模型:
    (使用 Controller )
    use App\Models\Publication;
    use App\Models\Resource;
    use App\Models\Source;
    ...
    ... Method ...
    $id_publication = 1;
    $id_resource = 1;
    $id_source = 1;

    $publication = Publication::find($id_resource);
    $resource = Resource::find($id_resource);
    $source = Source::find($id_resource);

    $publicationPivotColumns = [
    "notes" => "This is a note...",
    ];

    $sourcePivotColumns = [
    "catalog_number" => 100,
    "lot_number" => 4903,
    ];

    // Storing Data
    // Attach (Store in the publicationables table) a Publication to a Resource
    $resource->publications()->attach($publication, $publicationPivotColumns);

    // Attach (Store in the sourceables table) a Source to a Resource
    $resource->sources()->attach($source, $sourcePivotColumns);

    // Attach (Store in the sourceables table) a Source to a Publication
    $publication->sources()->attach($source, $sourcePivotColumns);

    // Retraiving Data
    // Get all Sources from a Resource
    $resource->sources()->get();

    // Get all Publications from a Resource
    $resource->publications()->get();

    // Get all Sources from a Publication
    $publication->sources()->get();

    关于Laravel 多态多对多关系数据透视表与另一个模型的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68073778/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com