0

I am creating a basic forum just so I have something meaningful to do while learning Laravel. So just like every forum is organized, on the main page i would like to have a list of categories and their subcategories, a total count of posts in every subcategory while also a link to latest post

So relationship is nested hasMany:

Category -> has Subcategories -> has Threads -> has Posts.

In controller method I have

$cat = Category::with('subcategory')->get();
return View::make('forum.index', compact('cat'));

and this works for basic list of categories and subcategories but I can't figure out the rest. This sure doesnt work

Category::with('subcategory')->with('threads')->with('posts')->get();

since relation between them is not set. Looking at Laravel docs, there is hasManyThrough relation. Is that a solution?

class Category extends Eloquent {

    public function subcategory()       {
        return $this->hasMany('Subcategory');
    }

    public function posts()     { // not sure about this cause it doesnt work
        return $this->hasManyThrough('Post', 'Thread');
    }
}

And on top of that how do I get posts->count() for every subcategory? Is it possible to have it split? Chaining could get complicated..

EDIT Table columns are

Categories

   id | title

Subcategory

   id | title | category_id

Threads

   id | title | subcategory_id | user_id  

Posts

   id | title | body | thread_id | user_id

EDIT 2 What would be the code for grabing only latest post? This doesnt work

$data =  Category::with('subcategories.threads')->with(array('posts' => function($query)
{
    $query->take(1);

}))->get();
Marko
  • 1,337
  • 5
  • 18
  • 37

2 Answers2

3

You have setup only one relation that works and that is:

class Category extends Eloquent {

    public function subcategory()       {
        return $this->hasMany('Subcategory');
    }
}

Declare other relationships in other models:

class Subcategory extends Eloquent {

    public function threads()       {
        return $this->hasMany('Thread');
    }
}

class Thread extends Eloquent {

    public function posts()       {
        return $this->hasMany('Post');
    }
}

Once you have declared relationships then you may use:

$categories = Category::with('subcategory.threads.posts')->get();

Since the one Category has many subcategories so use the plural name for subcategories instead of subcategory in your Category model, so for example, you may use:

class Category extends Eloquent {

    public function subcategories()       {
        return $this->hasMany('Subcategory');
    }
}

Then also:

$categories = Category::with('subcategories.threads.posts')->get();

All relationships will be retrieved as nested object collections. For example:

$categories->subcategories; // Will be a collection of Subcategory models
$categories->subcategories->threads // Will be a collection of Thread models
$categories->subcategories->threads->posts // Will be a collection of Post models

You may declare a hasManyThrough relationship between Subcategory and Post using something like this:

class Subcategory extends Eloquent {

    public function threads() {
        return $this->hasMany('Thread');
    }

    public function posts() {
        return $this->hasManyThrough('Post', 'Thread');
    }
}

Also, you may build a relationship between Category and Thread through Subcategory.

The Alpha
  • 143,660
  • 29
  • 287
  • 307
  • I had those relations set in models, but chaining with arrows didnt work, while your chaining with dots works perfectly. I am only worried about fetching everything, because i dont really want to grab all threads and posts, i just need to count them. But how would i load only latest post? I have edited my question. I was trying to expand your answer with example from laravel docs... thank you for your time :) – Marko Sep 12 '14 at 00:30
  • Use `$yourModel->orderBy('id', 'desc')->take(1)` – The Alpha Sep 12 '14 at 00:34
  • I tried that but the error is "Call to undefined method Illuminate\Database\Query\Builder::posts()". I guess i need a method 'posts' in Category model? but what to return there? – Marko Sep 12 '14 at 00:41
1

I have QuestionCategory and Questions['category_id'] and ItemsOfQuestion['question_id'] This Code has Work for my I hope that is useful for you

$categories=ExamCategory::with(['question' => function ($query) use($exam){$query->where('exam_id','=',$exam->id)->with('Items');}])->get();