如何根据数据透视表中两列(两个外键)中的 ID 返回相关模型?

Posted

技术标签:

【中文标题】如何根据数据透视表中两列(两个外键)中的 ID 返回相关模型?【英文标题】:How do I return related models based on IDs in two columns in pivot table (two foreign keys)? 【发布时间】:2014-11-20 15:50:56 【问题描述】:

我有一个包含以下列的数据透视表:

table - contributions
=====================
id          - int, pk
user_id     - int, fk
resource_id - int, fk
linked_id   - int, fk
...

这基本上在用户和资源之间创建了多对多的关系。现在,问题是,linked_id 也是一个外键,它指向资源表中的 ID。在大多数情况下,linked_id 将只是 null 并且不会成为问题。但有时,我希望将贡献链接到用户、资源和其他资源。

在我的资源模型中,我有以下代码:

public function contributions()

    return $this->hasMany('Contribution');

但是,如果我在其 ID 在linked_id 列中的资源上调用它,则不会返回任何内容。当在 resource_id 或 linked_id 列中找到资源的 ID 时,是否有某种方法可以返回所有行/关系? (不知何故有第二个 $foreignKey 值)。

【问题讨论】:

【参考方案1】:

嗯,选项:

1) 创建一个自定义查询,在其中检索资源,加入贡献表,在其中匹配资源对象中当前 id 上的 resource_id 或 linked_id。

类似:

SELECT R.* 
FROM resources AS R
INNER JOIN contributions AS C ON (
        C.`resource_id` = R.`resource_id`
    OR  C.`linked_id`   = R.`resource_id`
)
WHERE R.`id` = $Resource->id
GROUP BY R.`id`

2) 创建第二个关系方法linkedContributions,它与linked_id 列匹配。

public function linkedContributions()

    return $this->hasMany('Contribution', 'linked_id');

并检索数据:

$Resource = Resource::with(['contributions', 'linkedContributions'])->find(1);

3) 其他想法;您目前只能将 1 个资源链接到另一个资源。如果您创建一个额外的表 + hasMany 'linkedResources' 关系,您将能够将多个资源链接回当前资源。 (这里完全跳过这个问题)

【讨论】:

谢谢!我最终创建了一个类似于您的 #1 的解决方案。我很快就会在这里发布。【参考方案2】:

我在Resource 模型中修改了contributions 函数,如下所示:

public function contributions()

    return DB::table('contributions')
        ->where('resource_id', '=', $this->id)->orWhere('linked_id', '=', $this->id)
        ->join('resources', function($join) 
            $join
                ->on('resources.id', '=', 'contributions.resource_id')
                ->orOn('resources.id', '=', 'contributions.linked_id');
        )
        ->groupBy('contributions.id')
        ->select(
            'contributions.id', 'contributions.description', 'contributions.created_at', 'resources.id AS tileId', 'resources.name AS tileName',
            'users.id AS userId', 'users.username')
        ->get();

链接的贡献现在将显示在两个模型中,而无需为每个链接创建两个条目。

【讨论】:

以上是关于如何根据数据透视表中两列(两个外键)中的 ID 返回相关模型?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel 中的验证器检查两个表中两列的唯一性

mysql互换表中两列数据

如何减去 Power Query 数据透视表中的两列?

mysql互换表中两列数据方法

mysql互换表中两列数据方法

如何检索表的值以获取sql中两列的最大值