【问题标题】:Deep relations, *child* relation depends on *great-grandparent* id - with | load - Laravel/Eloquent深层关系,*child* 关系取决于 *great-grandparent* id - with |加载 - Laravel/Eloquent
【发布时间】:2022-02-23 02:58:20
【问题描述】:

我有这个数据库/模型结构(示例):

*食物类别 ------------ (id, name) - *不相关

食物 ---------------------- (id, food_category_id, name, ...)

配件组 ---------(id、name、...)

Foods_Accessory Groups - (food_id, acc_group_id) - 数据透视表

附件 ---------------- (id, acc_group_id, name, ...)

Foods_Accessories_Prices -(food_id、accessories_id、price - 数据透视表

模型

  • FoodCategory (hasMany: foods)
  • 食物(hasMany: foodAccessoriesGroup)
  • FoodAccessoriesGroup (hasMany: foodAccessory)
  • 有问题:*FoodAccessory(belongsToMany | belongsTo:food_prices | food_price ------ (枢轴:[价格],表格:food_accessory_prices,型号:Food)

测试:

**foods**
| id       | name |
| -------- | ---- |
| 1        | Pork |
| 2        | Eggs |

**accessory_groups**
| id     | name |
| -------| -----|
| 1      | Sauce|

foods_accessory_groups
| food_id  | accessory_group_id |
| -------- | --------------     |
| 1        | 1                  |
| 2        | 1                  |

**accessories**
| id       | name           | acc_group_id |
| -------- | -------------- | - |
| 1        | Mayo           | 1 |
| 2        | Ketchup        | 1 |

**foods_accessories_prices**
| food_id  | accessory_id   | price |
| -------- | -------------- | -     |
| 1        | 1              | 200   |
| 2        | 1              | 300   |
| 1        | 2              | 250   |
| 2        | 2              | 350   |

代码示例:

// get all food and relations
$foodCategories = FoodCategory::with([
  'foods',
  'foods.accessory_groups',
  'foods.accessory_groups.accessories',
  'foods.accessory_groups.accessories.food_prices' or
  'foods.accessory_groups.accessories.food_price' => function ($query) {
    // how to filter food prices by great-grandparent relation food (by food_id)
    // I know that it can't be done here, but where and how
  }
])->get();

配件动态价格取决于食物(曾祖父母关系)。 什么是这个问题的最佳实践和最优化的解决方案? 后处理或 Laravel Eloquent 有解决方案没有太多麻烦

food (id = 1, Pork) -> 有 foods_accessory_groups(id = 1, Sauce) -> 有配件(蛋黄酱和番茄酱),蛋黄酱价格是 200 ,番茄酱的价格是300。

food (id = 2, Eggs) - ... - ma​​yo价格是250,番茄酱价格是350。

API 响应来自示例:

【问题讨论】:

  • 向我们展示您的模型并提供您想要实现的示例输出。
  • 假设我想要这个 Api 响应。 ibb.co/ngBN0c3 将最后一个支点与他的(深层父母)食物联系起来的最佳做法是什么
  • 你不能在那个实例中调用数据透视表,因为该数据透视表在food <-> accessories之间,并且你正在调用accessories <-> accessoriesgroups之间的关系,如果你直接调用附件,你只能直接调用它食物模型,您需要建立从该数据透视表到通过附件组的食物的关系,建立原始查询可能更容易,但更好地定义模型之间的关系

标签: laravel eloquent relationship has-and-belongs-to-many belongs-to


【解决方案1】:

您可以使用whereHas 方法仅查询与您指定的条件有关系的FoodCategory 模型。

$foodCategories = FoodCategory::query()
    ->with([
        'foods',
        'foods.accessory_groups',
        'foods.accessory_groups.accessories',
        'foods.accessory_groups.accessories.food_prices' or
        'foods.accessory_groups.accessories.food_price' => function ($query) {
            // load only models from that relationship that match the condition(s)
            $query->where(...)
        }
    ])
    ->whereHas('foods.accessory_groups.accessories.food_price', function ($query) {
        // get only categories that have a nested relationship with condition(s)
        $query->where(...)
    })
    ->get();

【讨论】:

  • Tnx 的答案,但这不是我要找的。我不需要过滤食物类别。我需要配件来加载与曾祖父母关系食品相关的 food_price。食物(id = 1,猪肉)-> 有 foods_accessory_groups(id = 1)-> 有配件(蛋黄酱和番茄酱),蛋黄酱价格为 200,番茄酱价格为 300。对于食物(id = 2,鸡蛋)-.. .-蛋黄酱250,番茄酱350。
【解决方案2】:

您可以像这样直接访问accessories,并在您的 Foods 模型上显示价格

public function accessories() {
    return $this->belongsToMany( Accessory::class )->withPivot('price');
}

或在您的配件模型中执行相反的操作

public function foods() {
    return $this->belongsToMany( Food::class )->withPivot('price');
}

但由于您没有直接查询食物模型,因此您需要正确定义每个模型的关系,直到您的 FoodCategory 模型

【讨论】:

  • Tnx 寻求答案。我就这样使用它,但我不想让配件模型有食物,但只有一种食物。按曾祖父母(深层关系)过滤。 with( 'foods.accessory_groups.accessories.food' ) 其中最后一个 food 等于此关系中的曾祖父母 foods (第一个关系)
  • 检查hasManyThrough 关系并在您的附件模型中调用它,并参考FoodAccessoriesGroup 模型。或使用第三方软件包来建立您的关系,例如github.com/staudenmeir/eloquent-has-many-deep
猜你喜欢
  • 1970-01-01
  • 2013-12-14
  • 2021-03-06
  • 2022-01-25
  • 2018-05-21
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
相关资源
最近更新 更多