如何在孩子中使用hasMany,其中有belongsTo

Posted

技术标签:

【中文标题】如何在孩子中使用hasMany,其中有belongsTo【英文标题】:How to use hasMany which has belongsTo in the child 【发布时间】:2020-05-17 00:47:43 【问题描述】:

我有如下数据库关系

我想用他们的产品获取商店数据,每个产品都有自己的类别。如果我们在 Laravel 中使用 Eloquent ORM 定义它,购物 hasMany products belongsTo productCategory。

我可以使用hasMany 获取商店的产品数据,但我无法获取每个产品的productCategory。有谁知道如何获取每个产品的 productCategory 吗?

店铺型号:

class Shop extends Model
    
    public function products() 
        return $this->hasMany('App\Product');
    

产品型号:

class Product extends Model

    public function shop() 
        return $this->belongsTo('App\Shop');
    

    public function category() 
        return $this->belongsTo('App\ProductCategory');
    

产品类别型号:

class ProductCategory extends Model

    public function products() 
        return $this->hasMany('App\Product');
    

店铺控制器获取数据:

class ShopController extends Controller

    public function show(Shop $shop)
    
        $products = $shop->products()->get();
        return view('pages.shop-detail.index')->with('shop', $shop)->with('products', $products);
    

【问题讨论】:

请在问题中添加您到目前为止所做的查询以及关系的名称。 @porloscerrosΨ 当然,我已经添加了模型 哪里获取不到每个产品的productCategory?我猜你想在视图中显示它?你能告诉我们怎么做吗? 是的,我想在视图中显示一家商店的所有产品,但我也需要每个产品卡片的产品类别@porloscerrosΨ 这是哪个版本的 Laravel?它实际上对关系的 Eloquent 查询很重要。例如,如果它是 5.x* selectRaw 可能是您需要走的路。一切都取决于 【参考方案1】:

在One To Many (Inverse) 关系:

Eloquent 通过检查关系方法的名称并在方法名称后加上 _ 后跟主键列的名称来确定默认的外键名称。但是,如果 Product 模型上的外键不是 category_id,则应将自定义键名称作为第二个参数传递给 belongsTo 方法:

class Product extends Model

    public function category() 
        return $this->belongsTo('App\ProductCategory', 'product_category_id');
    

然后在视图中,遍历 shop products 并显示产品名称和产品类别名称:

<h3>Shop:  $shop->name </h3>
@foreach ($shop->products as $product)
    <p>Product:  $product->name </p>
    <small>Category:  $product->category->name </small>
@endforeach

但是……

以您在问题中的方式进行查询,当您在视图中循环查看产品时,您将遇到 N + 1 个问题。

避免控制器中的模型绑定急切加载关系并仅返回商店,产品和类别将急切加载到 Shop 对象上:

class ShopController extends Controller

    public function show($id)
    
        $shop = Shop::with('products', 'products.category')->find($id);

        return view('pages.shop-detail.index')->with('shop', $shop);
    

【讨论】:

哇,非常感谢。使用您的查询就可以了,我也在产品模型中添加了product_category_id,谢谢 不客气。以这种方式进行查询将避免循环视图时出现 N + 1 问题。它会按照你在问题中的方式工作,但对数据库来说会很紧张。我认为问题问题的答案是在关系中明确声明外键。

以上是关于如何在孩子中使用hasMany,其中有belongsTo的主要内容,如果未能解决你的问题,请参考以下文章

从父控制器创建新的 hasMany 孩子

用于从 hasMany 关系中检索一条记录的 Ember 计算属性?

在hasmany的续集中与计数

CakePHP - 如何一次通过记录保存单个 hasMany,每个 hasMany 有多个 belongsTo 记录?

如何从其中有孩子的div中获取文本

如何在 Laravel 的 hasMany 关系中使用 groupBy