Rainier laan
Rainier laan

Reputation: 1130

Laravel - Query builder get relation

In my project I have a Polymorphic relation. This relation is as followes:

Plugins
    id - integer
    composer_package - string

Themes
    id - integer
    composer_package - string

Products
    id - integer
    name - text
    ...
    commentable_id - integer
    commentable_type - string

When I need to display all the products that are a Theme I do the following:

$themes = DB::table('products')->orderBy('id', 'asc')->where('productable_type', Theme::class)->get();

The code above provides me with a list of all the products where the productable_type field is filled with App/Theme, I display them with a foreach loop like this @foreach($themes as $theme). Now my problem is. I need to get the composer_package from the themes table that belongs to that product. So say for instance. I get a product from the products table where the productable_id is 3. I want the value of the composer_package field in the themes table where the ID is 3. When I do {{ $theme->products->composer_package }} or {{ $theme->composer_package }} It gives me the error Undefined property What is causing this?

This is my product model

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


public function order_items()
{
    return $this->hasMany(Orderitems::class);
}

And this is my theme model

public function webshops()
{
    return $this->hasMany(Webshop::class);
}


public function products()
{
   return $this->morphMany(Product::class, 'productable');
}

Thanks in advance!

Upvotes: 1

Views: 1721

Answers (3)

kshitij
kshitij

Reputation: 710

Create relations with the model as mentioned in above answers, then you can retrieve relations using with helper. E.g.: Product::where('commentable_type', Theme::class)->with('commentable')->get();

and then can directly use as mentioned above. e.g.: $themeProduct->commentable

Upvotes: 0

Tudor
Tudor

Reputation: 1908

Is there any reason you are using the DB facade to pull data instead of the actual models?

One issue your are having is that your polymorphic relationship is stored in the commentable_id / commentable_type field, while your function name is product. Laravel does some of its magic just by naming alone, so let's make sure the column names and polymorphic function names match up in the product model:

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

After that, try something like this in the controller:

$themeProducts = Product::where('commentable_type', Theme::class)->get();

And this in the view

@foreach ($themeProducts as $themeProduct)
    {{ $themeProduct->commentable->composer_package }}
@endforeach

Upvotes: 1

Stormhammer
Stormhammer

Reputation: 497

Your table has "commentable", but your model is looking for "productable". You're also missing a method.

in your product model add:

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

in your theme model modify the products() method to:

public function products(){
   return $this->morphMany(Product::class, 'commentable');
}

You could also update your commentable_type and commentable_id columns in your table to productable_type and productable_id, in which case you need to rename commentable() in the code for the product model above to productable(), and 'commentable' to 'productable' in the code for the theme model above.

(Source: https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations)

Upvotes: 0

Related Questions