从hasMany关系和分页中获取所有对象


Getting all objects from hasMany relation and paginate

在我的Laravel应用程序中,我有一个类别列表页面。当用户单击某个子类别时,我希望列出所有产品,并对该结果使用分页。现在,我已经列出了与该子类别相关的所有产品,使用子类别ID:

public function subcategoryListing($slug){
    $products = Subcategory::find($idofSubcat)->products;
    return view('pages.subcategorylisting')
        ->with(array(
            'products' => $products,
        ));
}

这个结构包含三个类:CategorySubcategoryProducts。它们的声明如下:

<?php
namespace App;
use Illuminate'Database'Eloquent'Model;
use Illuminate'Database'Eloquent'Relations'Relation;
use App'Subcategory;
class Category extends Model
{
    protected $table = 'category';
    public $timestamps = false;
    public function subCategory(){
        return $this->hasMany('App'Subcategory', 'category_id');
    }
}

子类

<?php
namespace App;
use Illuminate'Database'Eloquent'Model;
class Subcategory extends Model
{
    protected $table = 'subcategory';
    public $timestamps = false;
    public function products(){
        return $this->hasMany('App'Products');
    }
}
产品

<?php
namespace App;
use Illuminate'Database'Eloquent'Model;
class Products extends Model
{
    protected $table = 'products';
}

对于每个模型类,我有一个表,结构如下:

Category
- id
- category_name
SubCategory
- id
- category_id
- subcategory_name
Products
- id
- subcategory_id
- product_title
- description
- price

我想要在我的页面中对从查询中检索到的结果进行分页。是否有更好的方法来获取与subcategory相关联的products并对它们进行分页?

在Eloquent (Laravel的ORM)中,当你调用关系作为属性($subCategory->products)时,它会根据关系类型(属于,有许多,…)返回相关对象或对象集合。相反,如果您将它作为一个函数($subCategory->products())调用,您将得到一个QueryBuilder实例。

请参阅http://laravel.com/docs/5.1/eloquent-relationships#querying-relations, 关系方法与动态属性一节了解更多详细信息。

无论如何,使用关系方法,您可以为您的集合调用paginate()。然后,考虑到这一点,您可以稍微更改代码以得到您想要的:
public function subcategoryListing($slug) {
    // I'm supposing here that in somewhere before 
    // run the query, you set the value to $idofSubcat 
    // variable
    $products = Subcategory::find($idofSubcat)->products()->paginate();
    return view('pages.subcategorylisting')
        ->with(array(
            'products' => $products,
        ));
}

我认为,创建两个类别表不太正确,最好使用下一个:

表类别

id    category_name   parent_id(nullable)  
产品和

 id          category_id        product_title      description     price

它更有用,你可以删除一个子类别模型并在类别中执行所有操作。

namespace App;
use Illuminate'Database'Eloquent'Model;
class Category extends Model
{
    protected $table = 'category';
    public $timestamps = false;
    public function subCategory(){
        return $this->belongsToMany('App'Category', 'categories', 'id', 'parent_id');
    }
    public function products(){
        return $this->hasMany('App'Products');
    }
}

和产品型号

<?php
namespace App;
use Illuminate'Database'Eloquent'Model;
class Products extends Model
{
    protected $table = 'products';
    public function category() {
         return $this->belongsTo('App'Category')
    }

}

,则可以得到查询结果

public function subcategoryListing($slug){
        $products = Category::find($idofSubcat)->products;
        return view('pages.subcategorylisting')
            ->withProducts($products); // it's a magic)) 
}

但是,存在着一个不漂亮的东西。你真的确定产品只属于一个类别吗?

我真的不明白你最初的一些功能:

// $slug is not being used anywhere within the function
public function subcategoryListing($slug){
    // $idOfSubcat isn't passed to this function so will throw an error
    $products = Subcategory::find($idofSubcat)->products;
    return view('pages.subcategorylisting')
        ->with(array(
            'products' => $products,
        ));
}

如果您想要做的是对属于特定subcategory_idProducts进行分页,如果您有subcategory_id,则以下代码将起作用:

$products = Product::where('subcategory_id', $idofSubcat)->paginate();

然后你可以把这个分页集合返回给你的视图,就像你已经做的那样:

return view('pages.subcategorylisting')
    ->with(compact('products'));