首页 文章

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

提问于
浏览
1

在主页中,我显示了产品的类别 . 数据库中有3个表在主页“部分控制”,“类别”和“产品”中发挥作用 . “section control”表包含节名称和与之关联的category_id . 'categories'表存储类别的名称,parent_id是父类别的id(从'categories'表本身的列表中选择 . 表示父表和子类的单个表)和'products'表有产品详细信息和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);
}

UPDATE 我通过在AppServiceProvider的启动函数中添加宏并在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;               
       });
    }); 

}

Controller

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 回答

  • 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

相关问题