I have two tables, products and pack_product
`product` table: product_id, model, price;
`pack_product` table: product_id, pack_id;
`product` table data:
product_id model price
1 model1 100
2 model2 150
3 model3 200
4 Pack1 300
5 Pack2 400
`pack_product` table data:
product_id pack_id
1 4
2 4
3 5
I registered all relationships in the Products model class and I would like to fetch all product data from the pivot table, but I getting empty array.
Products model:
/**
* Products can belong to many packs
*/
public function packs(){
return $this->belongsToMany(static::class, 'pack_product', 'products_id', 'pack_id');
}
/**
* Pack can have many products
*/
public function products(){
return $this->belongsToMany(static::class, 'pack_product', 'pack_id', 'products_id');
}
Controller
$products = new Products;
$products->products()->get();
// or
$product = Products::find(1);
$product->packs;
// getting [] output
UPDATE
The relations are connected right, but I cannot to print them.
Related
How to get only one value in the filament table for with hasMany relationship?
I have two DB tables:
products
id
sku
1
SKU_1
2
SKU_2
product_descriptions
id
product_id
translation_id
name
1
1
1
Opel
2
1
2
Vauxhall
In my Product model I have hasMany relationship
public function productDescriptions(): HasMany
{
return $this->hasMany(ProductDescription::class);
}
When I do Tables\Columns\TextColumn::make('productDescriptions.name') it return all values separated by comma. In my example "Opel, Vauxhall"
Is there any way to manipulate/mutate return value using callback? Let say, return only first value "Opel"?
You can use calculated states.
Tables\Columns\TextColumn::make('productDescriptions.name')
->getStateUsing( function (Model $record){
return $record->productDescriptions()->first()?->name;
});
categories
id
name
parent_id ?
products
id
name
category_id
In the category there can be both children and products
i need the count of products within the categories even it has children . Let's say categories have 2 products and 2 subcategories. both categories have 2 products each without subcategories. per category parent the count of products will be 6.categories can be parent->sub->sub 3 max.
class Category extends Model
{
public function activeChildren(): HasMany
{
return $this->hasMany(self::class, 'parent_id')
->active()
->with('activeChildren');
}
public function activeProducts(): HasMany
{
return $this->hasMany(Product::class)->where('is_active', true);
}
I'm wanting to do a joining table but I'm not sure how to set up the relationship in laravel.
I have 3 tables, products, categories, and product_categories. product_categories will consist of the product ID and the category ID. How would I join theses up in a relationship in laravel so I can just call $product->categories() like a normal relationship?
Your relationship will be belongsToMany.
Your products table would be
id | name
Your categories table would be
id | name
your product_categories table would be
id | product_id | category_id
As per relationship in Laravel
Product Model
class Product extends Model
{
protected $table = 'products';
public function categories()
{
return $this->belongsToMany('App\Category','product_categories','product_id','category_id');
}
}
Category Model
class Category extends Model
{
protected $table = 'categories';
public function products()
{
return $this->belongsToMany('App\Product','product_categories','category_id','product_id');
}
}
In controller now
Product::with('categories')->get();
This is a many-to-many relationship.
You can use belongsToMany on both products and categories and it would work. However you also should rename product_categories to follow the rule
use singular table names in alphabetical order
this would be category_product
I have two models that are related to each other with a belongsToMany relationship. The models are Game and Category. Of course, the tables for both are games and categories. The Category model, has its own parent-child relationship.
Basically this is my "simplified" structure:
Table game:
id unsigned integer
name string
Table categories:
id unsigned integer
name string
parent_id unsigned integer nullable
The parent_id column is null when the category has no parent, but it has an existing id referencing a row in the same table if it is a children of some other category.
Table category_game
category_id unsigned integer
game_id unsigned integer
The category_id column, references id on categories table. It should reference only the top category that a game belongs to. A game can belong to many different categories, but in the pivot table, there should only be a reference to the parents categories. For example if I had this structure of categories:
Category 1
Category 2
Category 4
Category 3
Category 9
Category 5
Category 6
Category 7
Category 8
I would like to have the following information for my games 1 and 2:
category_id game_id
3 1
5 1
1 2
And that should mean that my game 1 has categories: 3, 9, 5, 6, 7 and 8.
While my game 2 has categories: 1, 2, 4, 3 and 9
I understand that my Laravel models should have this:
class Game {
public function categories(){
return $this->belongsToMany( Category::class );
}
}
class Category{
public function games(){
return $this->belongsToMany( Game::class );
}
}
But I don't know how to retrieve the children categories using Eloquent. I know the belongsToMany method has more parameters that might help with my problem, but I don't know how to use them.
Model categoryGame for table category_game
class CategoryGame{
public function childCategories() {
return $this->hasMany(Category::class, 'parent_id','category_id');
}
}
You can access
$games = App\CategoryGame::all();
foreach ($games as $game ) {
foreach ($game->childCategories as $category) {
echo $category->name;
}
}
Let me know if not works
Extend your models:
class Category {
public function children() {
return $this->hasMany(Category::class, 'parent_id');
}
}
class Game {
public function getAllCategoriesAttribute() {
$result = collect();
$children = function($categories) use(&$result, &$children) {
if($categories->isEmpty()) return;
$result = $result->merge($categories);
$children($categories->pluck('children')->collapse());
};
$children($this->categories);
return $result;
}
}
Then you can access the categories like this:
Game::find($id)->allCategories;
I am using Laravel 5.5. I have a MySQL table implementation that contains
Table: regions
id name
1 NA
2 SA
3 AP
3 ASEAN
The user can create regions and allocate countries to them.
Pivot table: region_countries
id region_id country_id
1 1 1
2 1 2 ....
210 5 1
A country can belong to many regions, as the user can create a custom region, by grouping countries.
Table: countries
id name ....
1 Argentina....
A user belongs to a country, and thus to many regions
Table: Users
id name country_id
1 John Smith 32
My Country class contains:
/**
* Countries have many Regions
*/
public function regions()
{
return $this->hasManyThrough(Region::class, RegionCountry::class);
}
My Region class contains:
/**
* Regions have many Countries
*/
public function countries()
{
return $this->hasManyThrough(Country::class, RegionCountry::class);
}
So for the User class relationships, Is this the correct way to do this?
/**
* A User has a Country
*/
public function country()
{
return $this->belongsTo(Country::class, 'country_id');
}
/**
* A User has many Regions
*/
public function regions()
{
return $this->country()->hasMany(Region::class, 'region_id');
}
And the reverse, Region class has many Users
/**
* Regions have many Countries
*/
public function countries()
{
return $this->hasMany(Country::class, 'country_id');
}
/**
* Regions have many Users
*/
public function users()
{
return $this->countries()->hasMany(User::class, 'country_id');
}