Marko
Marko

Reputation: 1487

Laravel relations

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();

Upvotes: 0

Views: 2356

Answers (2)

Mohammad Khan
Mohammad Khan

Reputation: 41

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();

Upvotes: 1

The Alpha
The Alpha

Reputation: 146191

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.

Upvotes: 3

Related Questions