【问题标题】:Display products of a category and all its sub-categories in Laravel 5.2在 Laravel 5.2 中显示一个类别及其所有子类别的产品
【发布时间】:2019-01-02 23:39:20
【问题描述】:

在主页中,我显示产品的类别。数据库中有 3 个表在主页“部分控制”、“类别”和“产品”中发挥作用。 “部分控制”表具有部分名称和与之关联的 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);
}

更新我尝试了两种方式,在 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;               
       });
    }); 

}

控制器

   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 为空。子类别有自己的 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');
}

}

【问题讨论】:

  • 您将需要获取特定类别的整个类别树,然后查询产品表以获取在获取的类别数组中存在类别的所有产品。

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


【解决方案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

【讨论】:

  • 在我说它有效之后,我可能听起来很愚蠢。但我现在有问题。我应该在哪里定义宏?我在 FrontendController 的公共构造函数中定义它并访问它 getIndex() 并抛出“未定义属性:Illuminate\Database\Query\Builder::$children”$data['category_1_products'] = $section_control[3]->category ->递归();返回响应()->json($data);
  • 我通常会有一个抽象的基础模型类,并在它的构造函数中定义宏,其他在应用服务提供者中。你能用一个你如何使用它的例子来更新这个问题吗?
  • 请查看更新后的问题。可以给我你的 facebook id,我们可以彻底讨论一下吗?
猜你喜欢
  • 1970-01-01
  • 2012-09-02
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多