Laravel relations - php

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

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.

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

Related

How to get relation of relation Count in laravel?

i have laravel models
Category: id,name
public function posts(){
return $this->hasMany(PostCategory::class,'category_id','id');
}
PostCategory : post_id, category_id
public function post(){
return $this->belongsTo(Post::class,'post_id');
}
POST: id, ..so on
public function solutions(){
return $this->hasMany(PostSolution::class,'post_id','id');
}
I need to get count of all posts fall under a category and also solutions under one category.. there is no direct relation of category and solution so how to get count of solutions in one category.
$categories = Category::withCount('posts')->get();
I think use hasManyThrough relation
// Category Class
public function solutions()
{
return $this->hasManyThrough(PostSolution::class, Post::class);
}
// Then get the data in the same old manner
$categories = Category::->withCount('posts')->get();
I hope this will help

How do I get a field from a sub-relation in Laravel?

Objective:
Include category_name field in $posts attributes. The corresponding FK - category_id is currently included in my return.
Controller returns all Posts with their PostChilds
return $posts = Post::with('postchildren')->get();
Post Model hasMany PostChild
public function postchildren() {
$this->hasMany('App\PostChild')
}
PostChild Model hasOne Category
(This table has a category_id field which is a FK for id in the Category model.)
public function category() {
$this->hasOne('App\Category');
}
Category Model
This table has a category_name field
You should be able to get all the categories associated with the children via the HasManyThrough relationship e.g.
class Post
{
public function categories()
{
return $this->hasManyThrough(PostChild::class, Category::class);
}
}
Then you can access the categories directly on the post object e.g.
$categories = Post::first()->categories;
or if you're wanting an array of them something like
$posts = Post::with('categories')->get();
If you always want the categories loaded on the Post class you can define
class Post
{
protected $with = ['categories'];

Laravel.get one related record

There is two models: Category and Post.
class Category extends Model
{
public function posts()
{
return $this->hasMany('App\Post','category_id');
}
}
class Post extends Model
{
public function category()
{
return $this->belongsTo('App\Category');
}
}
//Get data
$data = Category::with(['posts' => function($query){
$query->orderBy('id','desc')->first();
}])->get();
In this case, all categories are displayed and only one post. I need to get from each category the one record post.
Example:
Category 1 - Post1
Category 2 - Post2
Category 3 - Post5
Category 4 - Post15
One category - one last post this category.
You have a Category with many Posts, but you just want to get the most recent post so you would add another relationship.
// Category.php
class Category extends Model
{
// This gets ALL posts
public function posts()
{
return $this->hasMany('App\Post','category_id');
}
// This gets the most recent post
// I am ordering by created_at instead of ID, but you can use ID
// if it makes sense for your application)
public function mostRecentPost()
{
return $this->hasOne('App\Post','category_id') // hasOne is the key here
->orderBy('created_at', 'DESC');
}
}
Then when you want to use it...
$data = Category::with('mostRecentPost')->get();

Create a lists of categories and their subcatgory in Laravel 5

I have three tables as category, subcategory and subcategory_category that I use to store the foreign key of other table in
I want to show a list with category and subcategory, such as:
category1
subcategory1
subcategory2
category2
subcategory3
subcategory4
I tried this but it is not OK
in my controller:
$mycategories = SubcategoriesCategories::with('parent')->with('children2')->get();
and in model:
class SubcategoriesCategories extends Model {
protected $table = 'subcategories_to_categories';
public function parent()
{
return $this->belongsTo('App\categories', 'categories_id');
}
public function children2()
{
return $this->belongsTo('App\subcategories', 'subcategories_id');
}
}
in mysubcategories_categories table i have:
For children operations you can use nested set technique, there is a library that can help you, it is called Baum https://github.com/etrepat/baum
I think you didn't configure your modeles right..
its should be like:
class Category{
public function subcategories(){
return $this->hasMany('app\subcategory')//or whatever is your relations
}
}
and than in controller:
$categories = Category::with('subcategories')->all();

Eloquent hasMany Inversion

I have three Eloqent models I would like to relate to each other (Category, Subcategory and Style) in the one-to-many style. The hasMany relationship is working correctly, but the inversion (belongsTo) is not.
The models are Paragon\Products\Category, Paragon\Products\Subcategory and Paragon\Products\Style. The tables look like this:
Category Paragon\Products\Category
ID ...
1
2
Subcategory Paragon\Products\Subcategory
ID Category ...
1 2
2 2
Style Paragon\Products\Style
ID Subcategory ...
1 1
2 1
The relationships look like this:
Category Paragon\Products\Category
public function subcategories() {
return $this->hasMany('Paragon\Products\Subcategory', 'category');
}
Subcategory Paragon\Products\Subcategory
public function styles() {
return $this->hasMany('Paragon\Products\Style', 'subcategory');
}
public function category() {
return $this->belongsTo('Paragon\Products\Category', 'category');
}
Style Paragon\Products\Style
public function subcategory() {
return $this->belongsTo('Paragon\Products\Subcategory', 'id', 'subcategory');
}
Ideally, I want to be able to call $subcategory->category(); and have an instance of Paragon\Products\Category returned. At the moment when I do this I get an instance of Builder returned. I assume I'm missing some kind of fetch method from my relationship...
Any help is appreciated, thanks!
This is what you want
$subcategories = $subcategory->with('category') -> get();
foreach ($subcategories as $row){
}

Categories