提问者:小点点

Laravel雄辩的嵌套查询


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

  • 类别
  • 产品
  • 类别产品

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

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

我进行了以下尝试,但没有成功:

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

显然,它会说category\u id不是一列。

这是我的数据库

身份证、姓名等。

ID、姓名、sku等。

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');

}

类别模型

class Category extends Eloquent {

protected $table = 'categories';

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

}

类别产品模型

<?php

class CategoryProduct extends Eloquent {

protected $table = 'category_products';

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

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

这是一个新问题

我想展示产品。如果类别未通过(值为-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_productsproduct_id,category_id列。

现在,查询:

$产品=产品::其中('状态', '=', '活动')-

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

任何想法,如何实现这一点。我希望我能摆脱困境。谢谢


共2个答案

匿名用户

除非除了product_id和category_id之外还有指向其他关系的其他字段,否则不需要使用CategoryProduct模型。

必要的是在类别产品模型上建立关系的方法。

类别中,添加关系函数...

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

在您的产品型号中,对类别执行相同的操作。

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

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

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

匿名用户

在多对多关系中,数据透视表不需要模型。请参阅雄辩的文档的这一部分,以获得进一步的解释。

您仍然需要创建迁移来设置数据透视表(如果不使用迁移,则手动进行),但不需要创建模型。相反,为类别创建一个函数来指定关系:

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
}

同样,产品也需要类似的公共功能。

然后你可以反过来做,找到类别,然后列出所有相关产品:

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

这个问题也可能与你的有关。