Question

Hi i thought i can handle this myself, but actually i don't know how to bite it.

I am trying to categorise my programs. There will be only 2 levels of categories:

1 CATEGORY
2 |-Subcategory

I want it to be as simple as possible.
- program can belong to only one subcategory,
- categories can have many subcategories,
- subcategories can have many programs,

Of course i would like to list all programs from subcategories, when someone choose a main category.

I am also not sure about my current database tables structure and relationship in models.

Tables in database:

programs: id, title, description, program_subcategory_id
programs_categories: id, name
programs_subcategories: id, name, program_category_id

Models:
Program.php

class Program extends Eloquent {
    protected $table = 'programs';
    public function user()
    {
        return $this->belongsTo('User');
    }
    public function subcategory()
    {
        return $this->belongsTo('ProgramSubcategory', 'program_subcategory_id');
    }   
}

ProgramCategory.php

class ProgramCategory extends Eloquent {
    protected $table = 'programs_categories';
    public function subcategories()
    {
        return $this->hasMany('ProgramSubcategory');
    }
}

ProgramSubcategory.php

class ProgramSubcategory extends Eloquent {
    protected $table = 'programs_subcategories';
    public function programs()
    {
        return $this->hasMany('Program');
    }
    public function category()
    {
        return $this->belongsTo('ProgramCategory');
    }
}

Actual controllers:
ProgramsController.php

class ProgramsController extends BaseController {
    public function index()
    {
        $programs = Program::with('subcategory')->orderBy('programs.id', 'desc')->paginate(5);    
        $acategories = ArticleCategory::All();
        $pcategories = ProgramCategory::All();
        return View::make('programs.index', compact('programs', 'acategories', 'pcategories'));
    }
}

ProgramsSubcatecories.php

class ProgramsSubcategories extends BaseController {
    public function index($cname)
    {
        $programs = ProgramSubcategory::whereAlias($cname)->first()->programs()->orderBy('id', 'DESC')->paginate(10);
        $pcategories = ProgramCategory::All();
        $scategories = ProgramSubcategory::All();
        $acategories = ArticleCategory::All();
        return View::make('programs.index', compact('programs', 'pcategories', 'scategories ', 'acategories'));
    }
    public function show($cname, $id)
    {
        $category = ProgramSubcategory::whereAlias($cname)->first();
        $program = $category->programs()->findOrFail($id);
        $pcategories = ProgramCategory::All();
        $acategories = ArticleCategory::All();
        return View::make('programs.show', compact('program', 'category', 'pcategories', 'scategories ', 'acategories'));
    }
}

It is not a problem for me to list all items from one category with eager loading. But i have problem how to do it with 2-levels categories.

Please advise how to start it.

Was it helpful?

Solution

You are not looking for eager loading, you need to solve how to manage hierarchical data in your database.

Nested sets model serves this purpose very well. You should read some theory on Wiki: http://en.wikipedia.org/wiki/Nested_set_model

Fortunately, there are Eloquent implementations already.
To mention some:
- Baum (the best free, imho), https://github.com/etrepat/baum
- Laravel Nested Set, https://github.com/atrauzzi/laravel-nested-set
- Laravel4-nestedset, https://github.com/lazychaser/laravel4-nestedset

and the paid one (surely highest quality as well)
from Cartalyst company - https://cartalyst.com/manual/nested-sets

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top