自我引用“无主”多人关系?

时间:2016-09-12 02:58:11

标签: laravel laravel-5 eloquent foreign-keys

我有很多关系,我不关心创建关系,如果查询模型ID在任何一方的关系我需要另一个侧。

-

假设我有这个模型

class Ingredient extends Model
{

    public function complements()
    {
        return $this->belongsToMany(
                   self::class, 'ingredient_complements', 
                   'ingredient_id', 'complement_id'
               );
    }

}

我已经创建了一些不同的实例,如下所示

$ing1 = new Ingredient();
$ing2 = new Ingredient();
$ing3 = new Ingredient();
$ing4 = new Ingredient();
$ing5 = new Ingredient();
$ing6 = new Ingredient();

$ing1->save(); //2,3,4,5,6...

接下来,我将介绍其中一些内容

$ing1->complements()->attach($ing2);
$ing2->complements()->attach($ing3);
$ing3->complements()->attach($ing4);
$ing4->complements()->attach($ing6);
$ing5->complements()->attach($ing6);
$ing6->complements()->attach($ing1);

现在我们有一个看起来像

的数据透视表
| ing_id | cmp_id |
| 1      | 2      |
| 2      | 3      |
| 3      | 4      |
| 4      | 5      |
| 5      | 6      |
| 6      | 1      |

所以..
如果我打电话$ing1->complements我会回来ing2
如果我打电话给$ing2->complements我会回来ing3

但是..
如果我致电$ing2->complements将不会取回ing1
如果我致电$ing3->complements取回ing2

我需要解决这个问题。

我有第二种方法,我现在正在使用$ing3->complementaryIngredients;进行调用,最终会执行类似

的操作
select * from `ingredients` 
inner join `ingredient_complements` on `ingredient_id` = '3' 
or `complement_id` = '3' and `ingredient_id` = `id` 
or `complement_id` = `id` where `id` <> '3'

哪个有效,但我觉得这不是我应该打破ORM的东西吗?

public function getComplementaryIngredientsAttribute()
{
    return self::join('ingredient_complements', function(JoinClause $join){
        $join->where('ingredient_id', $this->id);
        $join->orWhere('complement_id', $this->id);
        $join->on('ingredient_id', '=', 'id');
        $join->orOn('complement_id', '=', 'id');
    })->where('id', '<>', $this->id)->get();
}

1 个答案:

答案 0 :(得分:0)

您实际上需要定义双向关系,因此您的模型应该有另外一个方法来定义相反的方向。

public function ingredients()
{
    return $this->belongsToMany(
               self::class, 'ingredient_complements', 
               'complement_id', 'ingredient_id'
           );
}

然后,您将以这种方式获得关系的另一面$ing2->ingredients(),它将返回您要查找的内容。

另一种方法是为您的数据透视表创建模型,以便您可以查询该模型以获得关系的两面