【问题标题】:How to join 3 tables with Laravel's Eloquent relationships with Eager Loading?如何使用 Laravel 的 Eloquent 关系与 Eager Loading 连接 3 个表?
【发布时间】:2019-07-09 03:04:06
【问题描述】:

所以,order 有一个 foreign_key offer_id

offer 有一个foreign_key item_id

一件商品可能有多个报价。但是每个报价都有一个项目。

一个报价可能有多个订单。但是每个订单都有一个报价。

当我这样做时:

$orders = Auth::user()->orders()
            ->with('offer')
            ->get();

我明白了:

id: 3,
user_id: 1,
offer_id: 5,
created_at: "2019-02-15 00:40:31",
updated_at: "2019-02-15 00:40:31",
offer: {
    id: 5,
    item_id: 3,
    created_at: "2019-02-15 00:39:40",
    updated_at: "2019-02-15 00:39:40"
}

如您所见,我可以通过item_id: 3 获得此优惠 但我想得到整个项目;它的所有列,而不仅仅是 id。

通常,您会加入这两个表。 如何用 Eloquent 做到这一点?

这是我雄辩的人际关系:

订购

public function offer()
{
    return $this->belongsTo(Offer::class);
}

优惠

public function orders()
{
    return $this->hasMany(Order::class);
}

public function item()
{
    return $this->hasOne(Item::class);
}

物品

public function offers()
{
    return $this->belongsToMany(Offer::class);
}

【问题讨论】:

    标签: laravel eloquent eager-loading laravel-5.7 eloquent-relationship


    【解决方案1】:

    @MihirBhende 和@swonder 的答案指出了正确的方向。

    确实应该是:

    $orders = Auth::user()->orders()
                ->with('venue')
                ->with('offer.item')
                ->get();
    

    或(同样的事情):

    $orders = Auth::user()->orders()
                ->with(['venue', 'offer.food'])
                ->get();
    

    OfferItem 模型的关系应该颠倒:

    优惠

    public function item()
    {
        return $this->belongsTo(Item::class);
    }
    

    物品

    public function offers()
    {
        return $this->hasMany(Offer::class);
    }
    

    【讨论】:

      【解决方案2】:

      如果你所说的食物是指订单中的物品,那么:

      $orders = Auth::user()->orders()
                  ->with('offer', 'offer.orders', 'offer.item')
                  ->get();
      

      【讨论】:

      • 我收到了RelationNotFoundException Call to undefined relationship [items] on model [App\Order].
      • 你的项目中的items关系在哪里,是订单模型吗?
      • 请查看更新后的描述。我添加了关系。
      • 仍然无法正常工作:SQLSTATE[42S22]:找不到列:1054 'where 子句'中的未知列 'items.offer_id'(SQL:select * from items` where items.offer_id in (2, 4, 5))` 就我所见,它试图在 items 中寻找一个不存在的 offer_id。应该反过来。那么也许关系是错误的?
      • 您在报价模型中指定了一个关系,即预期 item_id 列。表结构是什么样的?
      【解决方案3】:

      Laravel Eager Loading

      在下面你会发现嵌套的急切加载:

      要急切加载嵌套关系,您可以使用“点”语法。例如,让我们在一个 Eloquent 语句中急切地加载本书的所有作者和作者的所有个人联系人:

      $books = App\Book::with('author.contacts')->get();

      在您的情况下,我们可以使用关系之间的点表示法获得嵌套的。

      $orders = Auth::user()->orders()
                  ->with(['offer', 'offer.item'])
                  ->get();
      

      【讨论】:

      • 你的意思是offer.items 不是offer.orders,对吗?它仍然无法正常工作 - RelationNotFoundException Call to undefined relationship [items] on model [App\Offer].
      • 你说offer有订单,order有商品。所以它会是offer.orders.items 来获取物品。在您的订单模型上,您必须定义与 Item 模型的关系。这似乎是$this->hasMany()。如果订单可以有很多项目。
      • 没有。订单有报价,报价有商品。看看我在描述的前两行中给出的外键,同时我更新它以包含我在代码中的关系。
      • 对不起,我读错了,所以应该是order.offers.items。我已经更新了上面的答案,应该可以正常工作。只要您的 Offer 模型与商品有关系。
      • @padawanTony 这不是物品,它只是物品,因为您的关系是 HasOne。所以请看我更新的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 2015-09-06
      • 2019-10-20
      • 1970-01-01
      相关资源
      最近更新 更多