Bring categories with multiple levels


I have in database a table of categories of up to three levels. In this I keep their subcategories recursively. The structure is this:

(pk) | id
     | nombre
     | slug
     | icono
(fk) | padre      <-- el id de su categoría padre o null si es de nivel 1

The categories of level 1 have subcategories of level 2 and those of level 2 have subcategories of level 3.

- 1:  categoria              nivel 1
    - 1001: categoria           nivel 2
        - 1001001: categoria       nivel 3
        - 1001002: categoria       nivel 3
        - 1001003: categoria       nivel 3
    - 1002:categoria            nivel 2
        - 1002001: categoria       nivel 3
        - 1002002: categoria       nivel 3
        - 1002003: categoria       nivel 3

Model of Categoria

class Categoria extends Model {

    protected $fillable = [ 'nombre', 'nivel', 'icono', 'padre', 'slug' ];

    public function subcategorias() {
        return $this->hasMany('App\Categoria', 'padre');


I try to bring all these categories to my view in the most efficient way possible, for the moment I do the following:

In CategoriaController

$categorias1 = Categoria::where('nivel', 1)

According to Laravel I'm doing nested eager loading , doing only three queries to bring all that data , instead of making a query for each category.

Now, despite having my table indexed and using eager loading , I would like to bring this data to respond much faster.


asked by Levi Arista 02.08.2018 в 00:56

1 answer


You can return all categories of level 1 (Parent = null). In your model you create a children function, and you place it to return the children of a father.

public function hijos()
  return $this->belongsTo('App\Categoria','id','padre');

And when you want to show the children of a category in your view, you only do:

@forearch($categorias as $categoria)
  @foreach($categoria->hijos as $hijo)
      {{ $hijo}}

You can also return all parents with their children:

$categorias = Categoria::all()->with('hijos')
answered by 13.08.2018 в 16:13