在Laravel 5.2中显示类别及其所有子类别的产品

时间:2018-07-26 04:24:08

标签: php laravel laravel-5 laravel-5.2 e-commerce

在主页中,显示产品类别。数据库中有3个表可用于主页“部分控制”,“类别”和“产品”。 “部分控件”表具有与它们关联的部分名称和category_id。 “类别”表存储类别的名称和parent_id,它是父类别的ID(从“类别”表本身的列表中选择。表示父类别和子类别的单个表)和“产品”该表包含产品详细信息和category_id。

现在,当我使用区域控件(后端)选择类别时,它仅显示该类别的产品。如果进一步选择的类别还有其他子类别,则不会在这些子类别上呈现产品。

部分控制模型:

class SectionControl extends Model
{

protected $table = "section_control";
protected $fillable = [
    'name', 'display_name', 'details', 'status', 'has_category', 'category_id'
];

public function category() {
    return $this->belongsTo('App\Models\Category', 'category_id')->with('children');
}

public function products() {
    return $this->category->hasMany('App\Models\Product', 'category_id');
}

}

类别模型:

class Category extends Model
{
protected $table = 'categories';

public function getRouteKeyName() {
    return 'slug';
}

public function children()
{
    return $this->hasMany('App\Models\Category', 'parent_id');
}

// recursive, loads all descendants
public function childrenRecursive()
{
    return $this->children()->with('childrenRecursive');
    // which is equivalent to:
    // return $this->hasMany('Survey', 'parent')->with('childrenRecursive);
}

// parent
public function parentCategory()
{
    return $this->belongsTo('App\Models\Category','parent_id');
}

// all ascendants
public function parentRecursive()
{
    return $this->parentCategory()->with('parentRecursive');
}

public function products() {
    return $this->hasMany('App\Models\Product', 'category_id');
}

public function childrenRecursiveIds() {
    return  $this->childrenRecursive()->pluck('id');
}

public function productsRecursive() {
    $products = \App\Models\Product::whereIn('category_id', $category_ids)->get();

    return $products;
}

}

产品型号:

 class Product extends Model
 {

protected $table = 'products';

public function getRouteKeyName() {
    return 'slug';
}

public function category() {
    return $this->belongsTo('App\Models\Category', 'category_id');
}


public function deals_of_the_week() {
    return $this->hasOne('App\Models\DealOfTheWeek', 'product_id');
}

}

控制器中的getIndex函数是:

    public function getIndex() 
   {
    $section_control = SectionControl::with('category')->get()->keyBy('id');

    $section = [
        'section_control_slider' => $section_control[1],
        'section_control_deals' => $section_control[2],
        'section_control_category_1' => $section_control[3],
    ];

    $data['main_sliders'] = MainSlider::where('status', 1)->orderBy('created_at', 'desc')->get();
    $data['deals_of_the_week'] = DealOfTheWeek::with('product')->orderBy('created_at', 'desc')->limit('20')->get();

     $data['category_1_products'] = $section['section_control_category_1']->products()->with('images')->limit(18)->orderBy('created_at', 'desc')->get();


    return view('frontend.home.index')
                    ->with($section)
                    ->with($data);
}

更新我通过在AppServiceProvider的启动函数中的addind宏和SectionContol模型中的构造函数中尝试了两种方式。他们都没有工作。也许我缺乏基础知识。

public function boot()
{
   Builder::macro('recursive', function () {
        return $this->children->map(function (Category $category) {
            if ($category->children->count()) {
                return $category->children->each->recursive();
            }

            return $category->products;               
       });
    }); 

}

控制器

   public function getIndex() {
    $section_control = SectionControl::with('category')->get()->keyBy('id');

    $section = [
        'section_control_slider' => $section_control[1],
        'section_control_deals' => $section_control[2],
        'section_control_category_1' => $section_control[3],
        'section_control_category_2' => $section_control[4],
        'section_control_featured' => $section_control[5],
        'section_control_category_3' => $section_control[6],
        'section_control_category_4' => $section_control[7],
        'section_control_category_5' => $section_control[8],
        'section_control_partners' => $section_control[9],
    ];

    $data['category_3_products'] = $section_control[4]->category->recursive();

    return response()->json($data);

}

我想再次解释这种情况。 我正在为部分分配类别。父类别具有唯一的category_id,parent_id为null。子类别具有其父类别的自己的category_id和parent_id。父级和子级都有单个表类别。 在产品表中,仅为产品分配了category_id。 如果分配给该部分的类别是子类别,则最初发布的代码可以解决问题。但是id类别是父类别,它什么也不显示。

以上,我忘记添加SectionControl模型。 在这里。

   class SectionControl extends Model
 {
protected $table = "section_control";
protected $fillable = [
    'name', 'display_name', 'details', 'status', 'has_category', 'category_id'
];

public function category() {
    return $this->belongsTo('App\Models\Category', 'category_id')->with('children');
}

public function products() {
    return $this->category->hasMany('App\Models\Product', 'category_id');
}

}

1 个答案:

答案 0 :(得分:1)

我会将protected $with = ['children'];添加到Category模型中,以便所有类别都渴望加载其子级。然后,您可以递归地遍历子类别以创建展平的产品数组:

use Illuminate\Database\Query\Builder;

Builder::macro('recursive', function () {
    return $this->children->map(function (Category $category) {
        if ($category->children->count()) {
            return $category->children->each->recursive();
        }

        return $category->products;               
   });
});


$products = $section_control->category->recursive();

Marcroable Trait