Reputation: 1130
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
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
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
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