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

时间:2014-09-25 18:49:38

标签: laravel-4 eloquent

我设置了一个数据透视表,其中包含以下列:

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

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

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

public function contributions()
{
    return $this->hasMany('Contribution');
}

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

2 个答案:

答案 0 :(得分:1)

嗯,选项:

1)创建一个自定义查询,在其中检索资源,加入与Resource对象的resource_id或linked_id匹配的contrib表,以及Resource对象的当前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 :(得分:0)

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

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();
}

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