首页 文章

Laravel Eloquent嵌套查询

提问于
浏览
3

我和Laravel一起工作,陷入困境 . 我有以下型号:

  • 类别

  • 产品

  • CategoryProduct

CategoryProduct 保存有关哪个产品属于哪个类别(产品可能属于多个类别)的信息 .

现在,当我想加载属于特定类别的所有产品时,我需要在 ProductCategoryProduct 上运行查询,这是我遇到的问题 .

我给了它以下尝试,但没有成功:

$products = Product::where('status', '=', 'active')
->where('category_id', '=', $category_id)
->take($count)
->skip($skip)
->get();

显然,它会说 category_id 不是一个专栏 .

这是我的数据库和模型结构:

类别表

身份证,姓名等

产品表

id,name,sku等

category_products表

id,product_id,(Product.id的外键)category_id,(Category.id的外键)等 .

产品型号

class Product extends Eloquent {

protected $table = 'products';

protected $hidden = array();

    public static $rules = array('name' => 'required|min:3');

}

Category model

class Category extends Eloquent {

protected $table = 'categories';

public static $rules = array('name' => 'required|min:3');

}

CategoryProduct model

<?php

class CategoryProduct extends Eloquent {

protected $table = 'category_products';

public function product()
{
    return $this->belongsTo('Product');
}

public function category()
{
    return $this->belongsTo('Category');
}
}

更新

A new question on this

我正在尝试展示产品 . 如果没有传递类别(值为-1),那么我将显示所有产品,否则我将显示已传递类别的产品 .

现在,当我展示所有产品时,这些产品可能已经存在于一个类别中 . 我想显示已经在类别中的产品的勾选复选框 . 我正在做这样的事情:

if($category_id==-1)
        $products = Product::where('status', '=', 'active')->take($count)->skip($skip)->get();
    else{
        $products = Product::whereHas('categories', function($q) use ($category_id)
        {
            $q->where('category_id', $category_id);
        })->where('status', 'active')
            ->take($count)
            ->skip($skip)
            ->get();
    }

category_products 将product_id,category_id作为列 .

现在,查询:

$ products = Product :: where('status','=','active') - > take($ count) - > skip($ skip) - > get();

将仅从 products 表中挑选产品 . 如果我在 category_products 中检查每个产品是否存在,那么对于大量产品将会有太多的数据库查询 .

任何想法,如何实现这一目标 . 我希望我能够清除我的情况 . 谢谢

2 回答

  • 1

    除非您有除product_id和category_id之外的其他字段指向其他关系,否则不应该使用 CategoryProduct 模型 .

    CategoryProduct 模型上设置关系的方法是必要的 .

    Category 中,添加关系函数...

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

    Product 模型中,对类别执行相同操作 .

    public function categories()
    {
        return $this->belongsToMany('Category', 'category_products');
    }
    

    然后,您可以使用关系方法查询属于该类别的活动产品 whereHas()

    $products = Product::whereHas('categories', function($q) use ($category_id)
    {
        $q->where('id', $category_id);
    })->where('status', 'active')
    ->take($count)
    ->skip($skip)
    ->get();
    
  • 1

    在多对多关系中,您不需要针对数据透视表的模型 . 请查看Eloquent文档的this section以获得进一步说明 .

    您仍然需要创建迁移以设置数据透视表(如果不使用迁移,则需要手动执行),而不是模型 . 而是为 Category 创建一个函数来指定关系:

    public function products()
    {
        return $this->belongsToMany('App\Product', 'category_products');
        // - You might need to adjust the namespace of App\Product
        // - category_products refers to the pivot table name
    }
    

    同样, Product 需要类似的公共功能 .

    然后你可以通过查找类别然后列出其所有相关产品来反过来做到这一点:

    $products = Category::find($category_id)
       ->products()
       ->where('status', 'active')
       ->take($count)
       ->skip($skip)
       ->get();
    

    This question也可能与您的相关 .

相关问题