Reputation: 14931
i was reading here:
Has one through Laravel Eloquent
but it does not solve the problem
we have manufacturerer names, for example:
kohler company
kohler
Kohler US
and these names we bundle together in one single clean name -> Kohler
so we have a table
manufacturer
and one
manufacturer_bundle
there exist products
created by those manufacturers
so a product has a manufacturer, and a manufacturer is linked to a manufacturer bundle.
But: not all products have a manufacturer entered. it can be empty. Or the manufacturer is not assigned to a manufacturer bundle.
I want to have a function
$product->manufacturer_bundle
currently i have to do
$product->manufacturer->manufacturer_bundle
I cannot write a function
public function manufacturer_bundle(){
return $this->manufacturer->manufacturer_bundle;
}
because $this->manufacturer
might be empty and I return nothing, I get an error: "Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation" . What is the correct laravel way to do this?
Upvotes: 0
Views: 4446
Reputation: 3075
The hasOneThrough
relationship has been added with version 5.8
https://laravel.com/docs/5.8/eloquent-relationships#has-one-through
Upvotes: 1
Reputation: 1672
ok .. you have three models ..
first is the ManufacturerBundle model as the peak of the hierarchy , add a function inside
public function manufacturers(){
return $this->hasMany('App\Manufacturers', 'bundle_id');
}
public function products(){
return $this->hasManyThrough('App\Products','App\Manufacturer','bundle_id','manufacturer_id');
}
model table structure must have:
'id' as primary key
'name' as the name of the manufacturer bundle
'and so on' . . . . . .
second is the Manufacturer model, that have data such as kohler company, kohler and Kohler US .. this model must belong to the manufacturer_bundle .. so we do inside the model a function like
public function bundle(){
return $this->belongsTo('App\ManufacturerBundle');
}
and so this also must have the products it have .. so
public function products(){
return $this->hasMany('App\Products','manufacturer_id');
}
model table structure must have:
'id' as primary key
'bundle_id' as the model manufacturerbundle id
'name' as the name of the manufacturer
'and so on' . . . . . .
as the last and the bottom of the hierarchy , we have Product model .. that should also belongs to the manufacturer .. so in the model we add a function
public function manufacturer(){
return $this->belongsTo('App\Manufacturer');
}
model table structure must have:
'id' again as primary key
'manufacturer_id' as the model manufacturer id
'name' as product name
'and so on' . . . . . . fields you want to add
and so the relations of our three model are now set. how you have several ways to call them
first using the bundle ..
$bundles = ManufacturerBundle::with('manufacturers.products')->get();
this will return you all bundles including it's manufacturer and their products ..
$bundles = ManufacturerBundle::with('products')->get();
this will return you all bundles including all products that belongs to the manufacturer this bundle have ..
second is by the product
$products = Product::with('manufacturer.bundle')->get();
this will return all products with their corresponding manufacturer and where this manufacturer is bundled. also those who do not have manufacturer will just leave its manufacturer as empty.
Upvotes: 4
Reputation: 523
I think you are looking for model mutators
In your case i should go for an accessor
For example:
public function getManufacturerBundleAttribute()
{
return $this->manufacturer->manufacturer_bundle;
}
Upvotes: 0