Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ranx99's avatar

How to structure this relation?

Models:

  • Lesson ( lessons table )
  • Video ( videos table )
  • Article ( articles table )
  • Audio ( audios table )

A lesson can have only one of the three models ( Video - Audio - Article ) as a content for the lesson.

How can I set the relation for this? So, when I do $lesson->content I get one of the three.

0 likes
6 replies
deepu07's avatar

@ranx99 So here you need to check with every model before retrieving. I think create one to one model relationship and pass a string along with the input. so based on string it will go and display into that model.

Sinnbeck's avatar

One way would be to have a custom attribute that handles this logic for you. Eg.

public function getContentAttribute()
{
    if ($this->type === 'video') {
        return $this->video;
    } else if ($this->type  === 'article') {
        return $this->article;
    }
}

And then have a relation for each (they can use the same column in the lesson table if needed.. Eg.

public function video()
{
    return $this->hasOne(Video::class, 'id', 'content_id');
    }
}

+1 for @ftiersch :)

Ranx99's avatar

So, I would use the polymorphic relationship like this:

After adding this line to lessons table:

$table->morphs('taggable');

then my model will be like:

class Lesson extends Model
{
    public function contentable()
    {
        return $this->morphTo('contentable');
    }
}

How can I save a Video, Article or an Audio to the lesson?

jlrdw's avatar

Or you could skip polymorphic and just use radio buttons to select one of the four types.

Not the same but similar to selecting a male or a female with radio buttons.

It's either one or the other.

Please or to participate in this conversation.