【问题标题】:Laravel get relationship, with distant relationships based on intermediateLaravel 获取关系,以中间关系为基础
【发布时间】:2015-01-16 14:59:11
【问题描述】:

情景

一个订单可以有多个订单行。每个订单行可以有许多产品。然后可以为每个产品分配一个许可证(但仅在订单完成后)。许可证将分配给单个用户。澄清一下,从技术上讲,每个订单行可以有一个或多个产品,并且没有,行上每个产品的一个或多个许可证。

型号

  • OrderHeader(id、状态、货币...)
  • OrderLine (id, order_header_id, total, ....)
  • 产品(id、name、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。许可证是单独添加的,但具有引用 User 和 OrderLine 的相关字段。

要求

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

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

关键是我想返回一个以这种方式正确加载关系的集合。

模型中的关系代码

订单页眉

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 检查。

谢谢!

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    试试下面的;

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

    当您从产品线而不是产品本身加载许可证时。然后在此基础上添加用户应该会为您提供所需的数据结构。

    【讨论】:

    • 导致 Builder.php 2006 行出现 BadMethodCallException:调用未定义的方法 Illuminate\Database\Query\Builder::license()
    • @BigPun 因为您将产品模型中的方法命名为“许可证”,所以将其更改为“许可证”。 / 我会更新答案。
    • 好地方!改变了这一点,我得到了与上一个答案和我自己尝试过的代码相同的错误:SQLSTATE [42S02]:找不到基表或视图:1146 表'homestead.exp_licence_product'不存在(SQL:选择@ 987654322@.*, exp_licence_product.product_id as pivot_product_id, exp_licence_product.licence_id as pivot_licence_id from exp_licences inner join exp_licence_product on id.=@9867654332@.@987 licence_id where exp_licence_product.product_id in (17)) 假设 licence_product 表存在
    • 查看belongsToMany关系方法的额外参数,这应该可以解决那个问题。
    • 不怕。我已将关系更改为 Product::belongsToMany('App\Licence', 'licences', 'product_id', 'id'); (许多许可证可以有相关产品的 product_id)。给出错误 SQLSTATE[42000]: 语法错误或访问冲突: 1066 Not unique table/alias: 'exp_licences' (SQL: select exp_licences.*, exp_licences.product_id as pivot_product_id, exp_licences.@ 987654342@ as pivot_id from exp_licences inner join exp_licences on exp_licences.id = exp_licences.id where exp_licences.product_id in (17)s>
    【解决方案2】:

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

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

    我也感觉到您的关系使用 belongsToMany() 不正确,因为我没有看到任何数据透视表,但没有看到您的架构,我无法确定。从你所拥有的来看,你应该使用的只是 belongsTo()hasOne()hasMany()

    【讨论】:

    • 我已经用核心字段更新了原始帖子以定义架构。数据透视表只是 order_line_product,它将多个产品连接到多个行。我尝试使用您的代码,但收到错误 SQLSTATE[42S02]: Base table or view not found: 1146 Table 'homestead.exp_licence_product' 不存在。看起来它正在尝试通过数据透视表将许可证加入产品,而不是从许可证中读取值
    猜你喜欢
    • 2022-01-27
    • 2015-11-29
    • 2018-12-13
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 2019-07-17
    • 2016-08-20
    相关资源
    最近更新 更多