Header Ads Widget

Ticker

6/recent/ticker-posts

Eloquent: Recursive tiene mucha relación con subcategorías ilimitadas

 Muy a menudo, en las tiendas electrónicas puede ver muchos niveles de categorías y subcategorías, a veces incluso ilimitadas. Este artículo le mostrará cómo lograrlo elegantemente con Laravel Eloquent.

Construiremos un mini-proyecto para ver las subcategorías de la tienda de los niños, cinco niveles de profundidad, como este:


Migración de base de datos

Aquí hay un esquema simple de la tabla DB:

Schema::create('categories', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name');
    $table->unsignedBigInteger('category_id')->nullable();
    $table->foreign('category_id')->references('id')->on('categories');
    $table->timestamps();
});

Solo tenemos un campo de nombre y luego una relación con la tabla en sí. Por tanto, la mayoría de las categorías principales tendrán category_id = NULL , y todas las demás subcategorías tendrán su propio parent_id.

Aquí están nuestros datos en la base de datos:


Modelo elocuente y relaciones

Primero, en app / Category.php agregamos un método simple hasMany () , por lo que la categoría puede tener otras subcategorías:

class Category extends Model
{

    public function categories()
    {
        return $this->hasMany(Category::class);
    }

}

Ahora viene el mayor "truco" del artículo . ¿Sabías que puedes describir una relación recursiva ? Me gusta esto:

public function childrenCategories()
{
    return $this->hasMany(Category::class)->with('categories');
}

Por lo tanto, si llama a Categoría :: con ('categorías') , obtendrá un nivel de "niños", pero Categoría :: con ('categorías de niños') le dará tantos niveles como pueda encontrar.


Método de ruta y controlador

Ahora, intentemos mostrar todas las categorías y subcategorías, como en el ejemplo anterior.

En route / web.php , agregamos esto:

Route::get('categories', 'CategoryController@index');

Entonces, app / Http / CategoryController.php se ve así:

public function index()
{
    $categories = Category::whereNull('category_id')
        ->with('childrenCategories')
        ->get();
    return view('categories', compact('categories'));
}

Como puede ver, solo cargamos categorías de padres, con los niños como relaciones. Simple, ¿eh?


Vista y subvista recursiva

Finalmente, a la estructura de Vistas. Aquí están nuestros recursos / vistas / categorías.blade.php :

<ul>
    @foreach ($categories as $category)
        <li>{{ $category->name }}</li>
        <ul>
        @foreach ($category->childrenCategories as $childCategory)
            @include('child_category', ['child_category' => $childCategory])
        @endforeach
        </ul>
    @endforeach
</ul>

Como puede ver, cargamos las categorías principales y luego cargamos las categorías secundarias con @include .

La mejor parte es que resources / views / admin / child_category.blade.php usará la carga recursiva de sí mismo. Ver el código:

<li>{{ $child_category->name }}</li>
@if ($child_category->categories)
    <ul>
        @foreach ($child_category->categories as $childCategory)
            @include('child_category', ['child_category' => $childCategory])
        @endforeach
    </ul>
@endif

Como puede ver, dentro de child_category.blade.php tenemos @include ('child_category') , por lo que la plantilla carga niños de forma recursiva, siempre que haya categorías dentro de la categoría secundaria actual.


¡Y eso es! Tenemos un nivel ilimitado de subcategorías: en base de datos, en relaciones elocuentes y en vistas.

Publicar un comentario

0 Comentarios