这是我的回答,希望能为您的问题带来一些启发。我已经发布了一个GitHub 存储库 https://github.com/ricardov03/polyrelations以及我在这里编写的所有代码的示例。我添加了有关如何在那里复制我的场景的更多信息。
数据库和关系
Here is my interpretation of the Database and its relations. You can check all the Migrations on the repository.
解决方案
问题一:
我应该如何保存可来源到出版物的枢轴行之间的关系?
Answer:
在继续代码示例之前,我想解释一些需要理解的重要概念。我将使用这个表达tag参考标识符 or index变形关系用于关联模型。
其工作方式是将标签分配给您想要添加到关系中的任何模型。使用这些标签的任何模型都可以存储在 Morph Pivot Table 中。 Laravel 使用 _"modelable"type列来过滤对存储模型名称的关系的调用。您可以使用关系“标记”您的模型,在模型中创建一个返回 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']);
}
}
在您的发布模型中,您有两种方法,一种与可来源的索引和另一个逆关系使用资源方法可出版的标签使用由许多变形作为回报。
发布模型 (./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:两者之间可以有一个中间表吗可来源的 and 可出版的链接到出版物?
Answer:
不,你不需要。您可以使用来源表来完成此操作。您始终可以通过创建返回源的方法将源与任何模型相关联变形对多与源模型的关系。这些是我们对出版物所做的问题1.
问题3:如何检索资源及其所有出版物以及所有相应出版物的来源?
Answer:
我认为 Eloquent 是整个 Laravel 框架中我最喜欢的功能。这是我们在模型定义上所做的一切的锦上添花。
如果您再次检查资源和发布模型定义,我们会添加一个withPivot()我们希望在对 eloquent 关系进行的任何调用中包含相关字段的方法。此方法可以从数据透视表中读取自定义值。
重要提示:对于此示例,我隐式添加了主元值,因为我在迁移时没有将这些列声明为 NULL。
要使用关系将发布与资源关联(存储在数据透视表上),您只需:
(Using 工匠修补匠)
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!"]);
(使用控制器)
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);
要从资源中检索所有出版物,您只需:
(Using 工匠修补匠)
Psy Shell v0.10.8 (PHP 8.0.6 — CLI) by Justin Hileman
>>> $resource = \App\Models\Publication::find(5)
>>> $resource->publications()->get();
容易吧? :) 雄辩的力量!
(使用控制器)
use App\Models\Resource;
...
$id_resource = 1; // This is the Resource Id you want to reach.
$resource = Resource::find($id_resource);
$resource->publications()->get();
以防万一,您可以通过以下方式存储和检索所有模型:
(使用控制器)
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();