Toskan
Toskan

Reputation: 14931

has one through relationship laravel

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

Answers (3)

whmkr
whmkr

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

Demonyowh
Demonyowh

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

Robert Fridzema
Robert Fridzema

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

Related Questions