如何在 Laravel 中创建多级菜单?

huangapple go评论69阅读模式
英文:

How to make multi-level menu in laravel?

问题

我正在构建一个具有大型菜单的电子商务网站,其中有大约10个主要类别,每个类别包含许多较低级别的子类别。例如,一个主要类别"PC组件"包含两个子类别:CPU和主板,然后CPU子类别包含Intel和AMD,然后Intel包含i3、i5和i7。我花了一些时间研究,发现这个问题可能可以通过具有父子关系和嵌套的foreach循环的关系数据库来解决,类似于以下方式:

// 控制器
... compact('maincategories')->toArray(); // 每个压缩后的主类别数组应包含所有子类别和孙子类别等。

// 视图
@foreach($maincategories as $maincategory)
   <h1>{{$maincategory['name']}}</h1>
      @foreach($maincategory['subcategories'] as $subcategory)
         <h2>{{$subcategory['name']}}</h2>
                  @foreach($subcategory['subcategory_level_2s'] as $subcategory_level_2)
                   <h3>{{$subcategory_level_2['name']}}</h3>
                  @endforeach
      @endforeach
@endforeach

然而,我不知道如何建立它们之间的关系。我已经知道hasMany和belongsTo关系,但如何使它们相互关联令人困惑。任何建议都将不胜感激。谢谢。

花了好几个小时,仍然无法设置SQL表之间的关系。

英文:

I'm building an ecommerce with a big menu where there are like 10 main categories, each of which contains many lower-level subcategories inside. For example, a main category "PC components" contains two sub-category of CPUs and Mainboards, then the CPU sub-category contains Intel and AMD, then Intel contains i3, i5, i7. I spent some hours researching and found that the problem might be solved by relational database with parent-child relations and nested foreach loops, somehow like below

//Controller
... compact(&#39;maincategories&#39;)-&gt;toArray (//each compacted maincategory array should contain all children and grandchildren, etc.);
//View
@foreach($maincategories as $maincategory)
   &lt;h1&gt;{{$maincategory[&#39;name&#39;]}}&lt;/h1&gt;
      @foreach($maincategory[&#39;subcategories&#39;] as $subcategory
         &lt;h2&gt;{{$subcategory[&#39;name&#39;]}}&lt;/h2&gt;
                  @foreach($subcategory[&#39;subcategory_level_2s&#39;] as $subcategory_level_2)
                   &lt;h3&gt;{{$subcategory_level_2[&#39;name&#39;]}}&lt;/h3&gt;
@endforeach
@endforeach
@endforeach


However, I don't know how to set up relationship between them. I already know hasMany and belongsTo relations, but how to make them relate to each other is confusing. Any suggestion is appreciated. Thanks.

Hours spent. Can't set up the relations with sql table.

答案1

得分: 1

你需要在迁移中设置外键。

示例如下。

第一步:使用Artisan命令创建迁移

php artisan make:migration create_category_layer1_table
php artisan make:migration create_category_layer2_table

create_category_layer1_table文件中:

public function up()
{
    Schema::create('category_layer1', function (Blueprint $table) {        
        $table->increments('id');
        $table->string('name');
    });
}

create_category_layer2_table文件中:

public function up()
{
    Schema::create('category_layer2', function (Blueprint $table) {        
        $table->increments('id');
        $table->string('name');
        $table->integer('category_layer1_id')->unsigned();
        $table->foreign('category_layer1_id')->references('id')->on('category_layer1');
    });
}

第二步:编写模型。

php artisan make:model category_layer1
php artisan make:model category_layer2

category_layer1是主要类别,category_layer2是子类别。假设category_layer1category_layer2之间的关系是一对多关系。因此,编写关系如下:

category_layer1模型中:

class category_layer1 extends Model
{
    public function category_layer2()
    {
        // 根据模型路径返回关系
        return $this->hasMany(\App\category_layer2::class);
    }
}

category_layer2模型中:

class category_layer2 extends Model
{
    public function category_layer1()
    {
        // 根据模型路径返回关系
        return $this->belongsTo(\App\category_layer1::class);
    }
}

最后一步:您可以在控制器中使用关系来获取数据。

在控制器中:

$main_category = Category_layer1::with(['category_layer2'])
                                ->whereNotNull('id')
                                ->get();
// 获取数据
foreach($main_category->category_layer2 as $category_layer2){
    \Log::info($category_layer2);
}

您可以创建更多您想要的类别。

如果您创建了更多类别,控制器中的代码如下:

// 根据类别级别数量
$main_category = Category_layer1::with(['category_layer2.category_layer3.category_layer4'])
               ->whereNotNull('id')
               ->get();
英文:

You need to set up foreign key in the migration.

Example as below.

First step: create migration by using artisan command

php artisan make:migration create_category_layer1_table
php artisan make:migration create_category_layer2_table

In the create_category_layer1_table file

public function up()
{
    Schema::create(&#39;category_layer1&#39;, function (Blueprint $table) {        
        $table-&gt;increments(&#39;id&#39;);
        $table-&gt;string(&#39;name&#39;);
    });
}

In the create_category_layer2_table file

public function up()
{
    Schema::create(&#39;category_layer2&#39;, function (Blueprint $table) {        
        $table-&gt;increments(&#39;id&#39;);
        $table-&gt;string(&#39;name&#39;);
        $table-&gt;integer(&#39;category_layer1_id&#39;)-&gt;unsigned();
        $table-&gt;foreign(&#39;category_layer1_id&#39;)-&gt;references(&#39;id&#39;)-&gt;on(&#39;category_layer1&#39;);
    });
}

Second step:Write Model.

php artisan make:model category_layer1
php artisan make:model category_layer2

The category_layer1 is the main categories, and the category_layer2 is the sub-category. Assume the relationship between category_layer1 and category_layer2 is One-To-Many.
Hence, writing the relationship as below

In category_layer1 model

class category_layer1 extends Model
{
    public function category_layer2()
    {
        // According to the model path
        return $this-&gt;hasMany(\App\category_layer2::class);
    }
}

In category_layer2 model

class category_layer2 extends Model
{
    public function category_layer1()
    {
        // According to the model path
        return $this-&gt;belongsTo(\App\category_layer1::class);
    }
}

Final step: You can use the relationship in the controller to get data.

In controller

    $main_category = Category_layer1::with([&#39;category_layer2&#39;])
                                     -&gt;whereNotNull(&#39;id&#39;)
                                     -&gt;get()
    // Get the data
    foreach($main_category-&gt;category_layer2 as $category_layer2){
        \Log::info($category_layer2);
    }

You can create more categories you want.

If you create more categories, the code in the controller like below

// According to how many category level    
$main_category = Category_layer1::with([&#39;category_layer2.category_layer3.category_layer4&#39;])
               -&gt;whereNotNull(&#39;id&#39;)
               -&gt;get()

huangapple
  • 本文由 发表于 2023年6月19日 11:17:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76503406.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定