简体   繁体   English

深层关系,*孩子*关系取决于*曾祖父母* id - 与 | 加载-Laravel/雄辩

[英]Deep relations, *child* relation depends on *great-grandparent* id - with | load - Laravel/Eloquent

I have this DB/Model structure (example):我有这个数据库/模型结构(示例):

* Food Category ------------ (id, name) - *irrelevant *食品类别 -------------- (id, name) - *不相关

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

Accessory Groups --------- (id, name, ...)附件组-------- (id, name, ...)

Foods_Accessory Groups - (food_id, acc_group_id) - pivot table Foods_Accessory Groups - (food_id, acc_group_id) - pivot 表

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

Foods_Accessories_Prices - (food_id, accessory_id, price ) - pivot table Foods_Accessories_Prices - (food_id, accessory_id, price ) - pivot 表

Models楷模

  • FoodCategory (hasMany: foods) FoodCategory(有许多:食物)
  • Food (hasMany: foodAccessoriesGroup)食物(有很多:foodAccessoriesGroup)
  • FoodAccessoriesGroup (hasMany: foodAccessory) FoodAccessoriesGroup(有许多:foodAccessory)
  • problematic : *FoodAccessory ( belongsToMany | belongsTo : food_prices | food_price ------ (pivot: [price], table: food_accessory_prices, model: Food)有问题的:*FoodAccessory ( belongsToMany | belongsTo : food_prices | food_price ------ (pivot: [price], table: food_accessory_prices, model: Food)

Test:测试: 桌子

**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   |

Code Example:代码示例:

// 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();

Accessory dynamic price is depended on Food (great-grandparent relation).配件动态价格取决于食物(曾祖父母关系)。 What is best practice and most optimize solution for this problem?这个问题的最佳实践和最优化的解决方案是什么? Post-process or Laravel Eloquent has solution without too much trouble后处理或者Laravel Eloquent 都有解决办法,不太麻烦

在此处输入图像描述

food (id = 1, Pork) -> has foods_accessory_groups(id = 1, Sauce) -> has accessories (mayo and ketchup) where mayo price is 200 , and ketchup price is 300. food (id = 1, Pork) -> has foods_accessory_groups(id = 1, Sauce) -> has accessories (mayo and ketchup) 其中蛋黄酱价格为 200 ,番茄酱价格为 300。

food (id = 2, Eggs) -... - mayo price is 250 , and ketchup price is 350. food (id = 2, Eggs) -... -蛋黄酱价格为 250 ,番茄酱价格为 350。

API response from example:来自示例的API 响应

在此处输入图像描述

You could use the whereHas method to query only FoodCategory models that have the relationship with the conditions you specify.您可以使用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();

You can directly access the accessories with prices on your Foods model like this您可以像这样在您的食品 model 上直接访问带有价格的accessories

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

or do the reverse inside your Accessories Model或者在你的配件里面做相反的事情 Model

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

but since you are not querying the food model directly you need to properly define the relationship for each model up until your FoodCategory model但由于您没有直接查询食物 model,因此您需要正确定义每个 model 的关系,直到您的FoodCategory model

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

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