Reputation: 991
My schema is as follows:
courses
-id
-title
-...
documents
-id
-...
videos
-id
-path
-...
course_resources
-id
-course_id
-type [docs OR videos]
-resource_id
Every course resource can be of multiple types, in this case documents or videos. How should one write the relationship in order to retrieve either the document or the video based on the type column in the course_resources pivot table? Obviously the resource_id can take either the value of video_id or of the document_id.
Ideally I would like something like this:
$course=Course::with('resources')->find(1);
foreach($course->resources as $resource){
//check resource type
//do something
}
Upvotes: 2
Views: 133
Reputation: 44526
You should use Many-to-Many Polymorphic Relations to accomplish this. Your course_resources
table structure is almost right, you need however to replace it with this table, so that Laravel can understand the relation and fetch the correct resources:
| coursable |
|------------------|
| course_id |
| coursable_id |
| coursable_type |
First you need to have three models for Course
, Document
and Video
. Then you need to add the polymorphic relations to the Course
model:
class Course extends Model
{
public function documents()
{
return $this->morphedByMany('App\Document', 'coursable');
}
public function videos()
{
return $this->morphedByMany('App\Video', 'coursable');
}
}
Now you can do the following to access resources, no more conditions needed to differentiate them:
// Eager load both relations
$course = Course::with('documents', 'videos')->find(1);
// Iterate over documents
foreach($course->documents as $document) {
// ...
}
// Iterate over videos
foreach($course->videos as $video) {
// ...
}
Upvotes: 2