morphTo and hasMany Laravel
Asked Answered
L

2

7

A quick query regarding some data model relations in Laravel.

I have a product, that belongs to a user, but a user can have many products. But a product can also have many people making an offer on that product so;

class Product extends Model
{
    public function user(){
        return $this->belongsTo('App\User');
    }
    public function offer(){
        return $this->hasMany('App\Offer');
    }

But a product can also have different sub types of product, for example, one might be a vehicle, or a mobile phone, each with different columns in my migration, so I assume I need morph many

In Product.php

public function imageable()
{
    return $this->morphTo();
}

In Vehicle.php

public function products()
{
  return $this->morphMany('App\Product', 'imageable');
}

However, when calling:

$product = Product::findOrFail($id);

I get null when I attempt do anything like $product->vehicle

I add the ID of the vehicle in my database to the imageable_id on the products table, and the imageable type to 'vehicle' on the products table too.

What am I doing wrong here?

Lang answered 10/5, 2017 at 15:0 Comment(0)
S
5

Everything looks right you just should be accessing it via imageable:

$product = Product::findOrFail($id);
return $product->imageable;

From the Laravel documentation:

You may also retrieve the owner of a polymorphic relation from the polymorphic model by accessing the name of the method that performs the call to morphTo.

In your case the method that performs the call to morphTo is imageable.

Selig answered 10/5, 2017 at 15:4 Comment(5)
Thats getting me further thank you, however I now get 'Class 'vehicle' not found'Lang
How are you storing the data in the polymorphic table? In the database the imageable_type should be like this: App\VehicleSelig
Ah you're right it was the App\Vehicle in the database, thanks Chase!! (i'll mark correct when SO lets me)Lang
Glad to hear I was able to help!Selig
You are fast, @chasenycAmimia
E
0

I think your use of imageable() as the name of the method in your Product model is what is throwing you off here...

you need to either:

  • rename the "imageable" method to vehicle() and then you can call $product->vehicle like you want to OR
  • keep the method called "imageable" but actually call the method by its name: $product->imageable
Enough answered 8/7 at 1:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.