属于Laravel 5中的数据透视表。

6
假设我有以下数据库模式:

enter image description here

dogsowners之间使用经典的belongsToMany进行连接。那么walks表怎么办?我希望能够在这种关系中使用Eloquent好处:

$dogs = Dog::with('walks')->get();
$walks = Walk::with('dogs')->get();

理论上,我可以用两个分开的列 dog_idowner_id 替换掉 dog_owner_id。这样使用 Eloquent 会更容易,但我会失去一些数据完整性,因为不相关的 Dog 和 Owner 可能会一起散步(这对它们都不安全!)。
Walk.php 中,应该如何定义关系?
public function dog() {
    // return ???;
}

那么 Dog.phpOwner.php 怎么样?

public function walks() {
    // return ???;
}

1
我相信你正在寻找HasManyThrough。可能我有些偏离,因为我已经很长时间没有做任何与Laravel相关的事情了。 - Andrei
我认为 hasManyThrough 对于 Dog.php 和 Owner.php 是有效的,但对于 Walk.php 不确定。 - Robo Robok
如果没有其他更好的方法,我想你可以使用旧的连接方式。在这里看看:https://laravel.io/forum/03-04-2014-hasmanythrough-with-many-to-many - Andrei
我在这篇文章中有类似的经历:https://stackoverflow.com/questions/44720436/how-to-get-multiple-joined-data-in-one-laravel-db-function 但我相信在Eloquent中没有标准的方法来解决这个问题。不过如果存在这样的方法,我很想看到它。 - Lars Mertens
如果这是你真正的结构,那么“walks”似乎与透视表相关有些奇怪。它确实是一种透视表 - “拥有者+狗=散步”,不是吗? - Jarek Tkaczyk
你好 :) 这不是真正的结构。但即使是这样,我认为它并不奇怪。例如,可以使用Pivot验证该特定人是否可以遛狗。然后,我可能想使用带有ondelete级联的外键,以便与被遗忘的狗主人对相关的任何散步也将消失。 - Robo Robok
2个回答

8

1- 创建四个模型(Walk,Dog,Owner,DogOwner)。

2- 在 Walk.php 模型中:

    public function dog()
{

    return $this->hasOneThrough(
        'App\Models\Dog',
        'App\Models\DogOwner',
        'id', // Local key on dog_owner table...
        'id', // Local key on dogs table...
        'dog_owner_id', // Foreign key on walks table...
        'dog_id' // Foreign key on dog_owner table...
    );
}

public function owner()
{

    return $this->hasOneThrough(
        'App\Models\Owner',
        'App\Models\DogOwner',
        'id', // Local key on dog_owner table...
        'id', // Local key on owners table...
        'dog_owner_id', // Foreign key on walks table...
        'owner_id' // Foreign key on dog_owner table...
    );
}       

3- 在 Dog.php 模型中

   public function walks()
    {
    return $this->hasManyThrough(
        'App\Models\Walk',
        'App\Models\DogOwner',
        'dog_id', // Foreign key on dog_owner table...
        'dog_owner_id', // Foreign key on walks table...
        'id', // Local key on dogs table...
        'id' // Local key on dog_owner table...
    );
    }   

4- 在Owner.php模型中

   public function walks()
   {
    return $this->hasManyThrough(
        'App\Models\Walk',
        'App\Models\DogOwner',
        'owner_id', // Foreign key on dog_owner table...
        'dog_owner_id', // Foreign key on walks table...
        'id', // Local key on owners table...
        'id' // Local key on dog_owner table...
    );
   }

现在有了 Laravel 中的 PivotModel,实现起来就更容易了。不过我现在用另一种方法,今天我只会把 dog_idowner_id 放到 walks 表中。 - Robo Robok
当关系是多对多时,例如(作者,帖子,作者_帖子),透视表运作良好。但在walk表中,关系通过透视表是一对一的。而在(狗,主人)表中,关系通过透视表是一对多的。 - Esraa Gamal
我相信这可能会有所帮助。它确实解决了我的问题。https://laravel.io/forum/12-28-2014-belongsto-relationship-with-pivot-table - Mr.Singh

0

正如其他人所提到的,您可以使用HasManyThrough来实现此功能:

https://laravel.com/docs/5.5/eloquent-relationships#has-many-through

就像你所说的,这对于你的狗和主人模型是有效的。对于你的步行模型来说,它有点不同,但你有一个很好的选项可以自己映射查询:

return $this->hasManyThrough(
    'App\Post',
    'App\User',
    'country_id', // Foreign key on users table...
    'user_id', // Foreign key on posts table...
    'id', // Local key on countries table...
    'id' // Local key on users table...
);

你确定吗?每次遛狗只有一只狗和一个主人(至少在我的世界里是这样的:P)。 - Robo Robok
当然,你定义了两个方法。 - Stephan-v
我的意思是,hasManyThrough 的设计是用于查询多条记录,而不是一条。 - Robo Robok
我真的怀疑在Eloquent中是否有一种“标准方法”可以完成这个任务。 - Stephan-v
而且,在这种情况下,我需要基于枢轴创建一个虚假模型,类似于“DogOwnerPair”。 - Robo Robok
我已经测试过了,这种方式可以正常工作:在Dog类中使用return $this->hasManyThrough(Walk::class, DogOwnerPair::class, 'dog_id', 'dog_owner_id');。但是让它对Walk起作用则更加困难。 - Robo Robok

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接