作为中间表创建的项目表的 Eloquent Relation

Posted

技术标签:

【中文标题】作为中间表创建的项目表的 Eloquent Relation【英文标题】:Eloquent Relation for items table which was created as intermediatary table 【发布时间】:2019-07-30 09:22:50 【问题描述】:

我有 3 张桌子 - 书籍、订单、物品

我将订单数据(order_id,user_id) 保存在订单表中,并且图书 ID 保存在 Items 表中,因为用户可以添加多本书。

书籍

+++++++++++++++++++++++++++++
+ id    book_code    name   +
+++++++++++++++++++++++++++++
   1     abc         Book 1
   2     def         Book 2

订购

+++++++++++++++++++++++++++++
+ id  user_id               +
+++++++++++++++++++++++++++++ 
  1    1

物品

++++++++++++++++++++++++++++++++++
+ id order_id book_id  quantity  +
++++++++++++++++++++++++++++++++++
  1    1        1         2
  1    1        2         3

我正在尝试显示在订单 ID 下预订的订单详细信息和书籍,但我对使用这些关系感到困惑。 由于所有数据都存储在 Order 表中,因此我能够成功显示订单详细信息。 但我无法显示订购到相应订单 ID 的书籍

示范书

public function items()

    return $this->hasMany(Items::class);

模型订单

public function items()

    return $this->hasMany(Items::class,'order_id');

控制器

public function user_order_details($payment_orderid)

    // dd($payment_orderid);  //payment_orderid  = 1
    $order_details = Orders::find($payment_orderid);
    $order_products = Orders::find($payment_orderid)->items;
    $books = Books::with('items')->get();
    dd($books);

路线

Route::get('orders', 'UserDashboardController@user_order');  // I will be fetching the user orders based on the ID from Orders table
Route::get('orders/payment_orderid', 'UserDashboardController@user_order_details'); // Here I would like to show the details related to the order 

我能够获取结果,但我不确定如何将结果隔离到 order_id。

如果我的数据库实现错误且不可扩展,我愿意接受建议。

简而言之,我正在尝试显示相应订单的图书详细信息

注意: 如果投反对票,请确保您评论原因。对于过去的几个问题,我无缘无故地被否决了

【问题讨论】:

@Rwd 我已将我的订单模型添加到问题中 您展示的 3 个表中的哪一个与 OrderProducts 相关...或者它完全是一个单独的表? @Rwd 很抱歉不清楚,我已经为问题添加了更多细节,希望上面的编辑包含所有信息:) OrderProducts 模型用于什么表?您已经展示了 3 个表 booksorderitems...是其中之一还是您也有 order_products 表? 忘记重命名了 :( . OrderProducts 代表 Items 表 【参考方案1】:

首先,您不需要再次查询Order,因为您已经在上面的行中找到了它,即

$order_details = Orders::find($payment_orderid);
$order_products = Orders::find($payment_orderid)->items;

可以是:

$order_details = Orders::find($payment_orderid);
$order_products = $order_details->items;

其次,如果您想通过订单获得books,您可以在Order 模型上建立belongsToMany 关系或在Items 模型上建立hasOne 关系(或两者)。

BelongsToMany

将以下内容添加到您的 Orders 模型中:

public function books()

    return $this->belongsToMany(Books::class, 'items')
        ->withPivot('quantity')
        ->withTimestamps();

然后在你的控制器中你可以这样做:

$order_details = Orders::find($payment_orderid);
$books = $order_details->books; //Each book with have a `pivot` property than contains  the  quantity.

有一个

在您的 Items 模型中,您可以添加以下内容:

public function book()

    return $this->hasOne(Books::class);

然后在您的控制器中,您可以使用eager loading 来获取物品和书籍:

$order_details = Orders::with('items.book')->find($payment_orderid);
$order_products = $order_details->items; 

在上面每个order_product 上都会有一个books 属性,即

foreach ($order_products as $order_product) 
    $order_product->book->name;

【讨论】:

非常感谢兄弟,花了一段时间才使解决方案生效。我继续 BelongsToMany。我必须添加 order_id 才能使解决方案正常工作 public function books() return $this->belongsToMany(Books::class, 'order_products', 'order_id') ->withPivot('quantity') ->withTimestamps( ); 我对 laravel 中的关系感到非常困惑。你能分享我关于关系的教程吗:) @mightyteja 这将是更好的教程之一:laracasts.com/series/eloquent-relationships,但是,它确实需要订阅。【参考方案2】:

据我了解,您的 items 表是订单和书籍的数据透视表。所以你可以这样做:

订单模式

public function books()

    return $this->belongsToMany('App\Book', 'items', 
      'order_id', 'book_id');

items 是数据透视表。

在控制器中:

public function user_order_details($payment_orderid)

    $order_details = Orders::find($payment_orderid);
    foreach ($order_details->books as $product)
    
       echo $product->name;
    

【讨论】:

以上是关于作为中间表创建的项目表的 Eloquent Relation的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Eloquent ORM 中按多对多关系的数据透视表的字段进行排序

Laravel Eloquent 多列 IN 子句

使用 Eloquent 获取连接表的最新值

Laravel Eloquent 表之间通过其他表的关系

Eloquent hasManyThrough 也获取中间表信息

Eloquent中一对多关系表的分组和总和