Eloquent hasMany Inversion - php

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){
}

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

Laravel Eloquent - how to get only 2 child of each parent using Eloquent?

I want to get category with only 2 subcategory not all subcategory. Like below output
Category 1
subcategory 1,
subcategory 2,
Category 2
subcategory 1,
subcategory 2,
Category 3
subcategory 1,
subcategory 2
Total 5 category and each category have 5 subcategory
Category.php
class Category extends Model {
public function subcategory(){
return $this->hasMany('App\Subcategory');
}
public function limitSubcategory(){
return $this->hasMany('App\Subcategory')->limit(2);
}
}
Subcategory.php
class Subcategory extends Model {
public function category(){
return $this->belongsTo('App\Category');
}
}
HomeController.php
Method 1:
Category::with(['limitSubcategory' => function($query) {
}])->get();
Method 2:
Category::with(['subcategory' => function($query) {
$query->limit(2);
}])->get();
But it get only 2 subcategory in first category.
Click here to view output
Please help me, How to get?
you can use the trait: HasEagerLimit:
you can install it:
composer require staudenmeir/eloquent-eager-limit:"^1.0"
and then in your model:
class Category extends Model {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
public function subcategory(){
return $this->hasMany('App\Subcategory');
}
public function limitSubcategory(){
return $this->hasMany('App\Subcategory')->limit(2);
}
}
and also in SubCategory model:
class Category extends Model {
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
}
now : when you load your relation ... it should return the result you desire:
$results=Category::with('limitSubcategory')->get();
more details in:
https://github.com/staudenmeir/eloquent-eager-limit
In your controller when you retreive Category like this $categ = Category::all() you can have your limited list with $categ->limit_subcategory
If you want to optimise request with eager loading and not have N+1 problem in sql request you can do $categ = Category::whth(['limitSubcategory']->get()
Read this part of documentation for more informations about eager loading https://laravel.com/docs/7.x/eloquent-relationships#eager-loading

Laravel - Eloquent 3 Table Query

I know there are several questions out there on 3 table joins, but the examples are simpler than my set up.
I have three tables: Items, Attributes, Categories.
`item.item_code = attributes.item_code`
`attributes.category_id = category.id`
Using eloquent, I can access attributes no problem with:
$items = Item::with('attributes')->paginate(15);
But I can't seem to get the relationship set correctly to retrieve the category name.
With a standard MySql query I'd use something like:
SELECT category_name FROM items
JOIN attributes on items.item_code = attributes.item_code
JOIN categories on attributes.pg3_id = categories.id
WHERE items.item_code = 40992264
How do I achieve this using eloquent?
Edit - My bad - Totally messed up the SQL. Updated to reflect the correct table names and include the second join
Update
My models currently look like this:
class Attributes extends Model
{
public function category(){
return $this->belongsTo(Category::class);
}
}
class Product extends Model
{
public function item()
{
return $this->belongsTo(Item::class);
}
}
class Category extends Model
{
public function attributes()
{
return $this->belongsTo(Attributes::class);
}
}
But this still isn't returning a result. I've tried using
$items = Item::with('attributes.category')->get();
as suggested, but this still throws an error. If I update the Product model to:
class Product extends Model
{
public function item()
{
return $this->belongsTo(Item::class);
}
public function category(){
return $this->belongsTo(Category::class);
}
}
I don't get an error, but the relationship returns null.
You can do
$items = Item::with('attributes.category')->get();
So you access the category relationship inside the attributes relationship.
For example:
foreach ($items as $item) {
foreach ($item->attributes as $attribute) {
echo $attribute->category->id; // Will print the category id.
}
}

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

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

Categories