繁体   English   中英

Laravel获得关系,基于中间关系具有远距离关系

[英]Laravel get relationship, with distant relationships based on intermediate

场景

一个订单可以有多个订单行。 每个订单行可以有很多产品。 然后,可以为每个产品分配一个许可证(但仅在订单完成后)。 许可证将分配给一个用户。 需要澄清的是,从技术上讲,每个订单行可以具有一个或多个产品,而该行中每个产品都不能具有一个或多个许可证。

楷模

  • OrderHeader(id,状态,货币等)
  • OrderLine(id,order_header_id,总数,...)
  • 产品(ID,名称,parent_id)
  • 许可证(id,user_id,product_id,order_line_id)
  • 用户(ID,名称,电子邮件等)

还有一个order_line_product表,其中包含order_line_id和product_id字段。

因此,订单包含OrderHeader表中的一条记录以及OrderLine表中的许多记录,这些记录通过order_line_product表链接到Product。 许可证是单独添加的,但具有相关字段以引用用户和订单行。

需求

我想以以下格式输出日期:

OrderHeader
 - OrderLine 1
   - Product 1
     - Licence 1
       - User 1
     - Licence 2
       - User 2
   - Product 2
      - Licence 3
        - User 3
 - OrderLine 2
   - Product 1
 - OrderLine 3
   - Product 1
   - Product 2
     - Licence 4
        - User 4
   - Product 3

关键是我想返回一个Collection,并且以这种方式正确加载了关系。

模型中的关系代码

OrderHeader

public function lines()
{
    return $this->hasMany('App\OrderLine', 'order_header_id', 'id');
}

订单行

public function header()
{
    return $this->belongsTo('App\OrderHeader', 'order_header_id');
}

public function products()
{
    return $this->belongsToMany('App\Product');
}

public function licences()
{
    return $this->hasMany('App\Licence');
}

产品

public function orderLine()
{
    return Product::belongsToMany('App\OrderLine');
}

public function licence()
{
    return Product::belongsToMany('App\Licence');
}

执照

public function user()
{
    return Licence::belongsTo('App\User');
}

public function line()
{
    return Licence::belongsTo('App\OrderLine', 'order_line_id');
}

public function product()
{
    return Licence::hasOne('App\Product', 'id', 'product_id');
}

希望所有流程都按预期进行。

当前代码

如果我使用:

$order = OrderHeader::findOrFail($id)->load('lines.products', 'lines.licences.user', 'creator');

它非常接近我想要的输出,所有正确的数据都存在,但是“许可证”关系并不嵌套在“产品”关系中。 如果我输出数据,它将采用以下格式:

OrderHeader
 - OrderLines
   - Products
      - Product 1
      - Product 2
      - etc...
   - Licences
      - Licence 1
        - User
      - Licence 2
        - User
      - etc...

即,许可证与产品处于相同的层次结构级别,而不是嵌套在其中。

我想要的是:

OrderHeader
 - OrderLines
   - Products
     - Product 1
       - Licences
         - Licence 1
           - User

这将使我能够非常轻松地遍历订单的整个层次结构,而不必进行混乱的foreach / if检查。

谢谢!

尝试以下方法;

$order = OrderHeader::findOrFail($id)->load('lines.products', 'lines.products.licence','lines.products.licence.user', 'creator');

从线路而不是产品本身加载许可证时。 然后,在此之上添加用户将为您提供所需的所需数据结构。

当您说要在产品上使用许可证时,就是在向用户加载许可证。 试试这个吧。

$order = OrderHeader::findOrFail($id)->load('lines.products.licence.user');

我也有一种感觉你的人际关系被错误地使用belongsToMany()因为我没有看到任何数据透视表,但没有看到您的架构,我不能肯定。 从您所拥有的来看,您应该使用的所有东西似乎是belongsTo()hasOne()hasMany()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM