Polymorphic Has One or Many
For polymorphic relations like has-one-polymorphic or has-many-polymorphic, you can just simply set it as morphTo
, and the parent model as morphOne
and morphMany
. As always, no need to declare the model if Larawiz can guess it from the relation name.
Stranded in an ID-land
Because of the nature of Eloquent ORM polymorphic relations, only parent models using numeric or UUID primary keys are supported.
If you are using a custom primary key, you may create this type of relation after you receive your scaffolded app.
In this example, both Student
and Teacher
share one Classroom
, and share many Courses
. The polymorphic relations will be fully aware of the names, and the migrations for both Classroom
and Course
will include the polymorphic columns automatically.
models:
Student:
name: string
classroom: morphOne
courses: morphMany
Teacher:
title: string
classroom: morphOne
courses: morphMany
Classroom:
name: string
assistable: morphTo
Course:
name: string
coursable: morphTo
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Student extends Model
{
public function classroom()
{
return $this->morphOne(Category::class, 'assistable');
}
public function courses()
{
return $this->morphMany(Course::class, 'coursable');
}
}
class Teacher extends Model
{
public function classroom()
{
return $this->morphOne(Category::class, 'assistable');
}
public function courses()
{
return $this->morphMany(Course::class, 'coursable');
}
}
class Classroom extends Model
{
public function assistable()
{
return $this->morphTo();
}
}
class Course extends Model
{
public function coursable()
{
return $this->morphTo();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Schema::create('photos', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->timestamps();
});
Schema::create('videos', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->timestamps();
});
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->morphs('categorizable');
$table->timestamps();
});
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->morphs('taggable');
$table->timestamps();
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
I'm a wizard, not a psychic
When the child model has many morphTo
relations, you will need to pick one, like morphOne:Classroom,assistable
.
If all the related models use UUID as primary key, don't worry, Larawiz will automatically change the migration column to use uuid
.
models:
Photo:
id: uuid
title: string
category: morphOne
Video:
id: uuid
title: string
category: morphOne
Category:
name: string
categorizable: morphTo
2
3
4
5
6
7
8
9
10
11
12
13
14
class Photo extends Model
{
public function category()
{
return $this->morphOne(Category::class, 'categorizable');
}
}
class Video extends Model
{
public function category()
{
return $this->morphOne(Category::class, 'categorizable');
}
}
class Category extends Model
{
public function categorizable()
{
return $this->morphTo();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Schema::create('photos', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('title');
$table->timestamps();
});
Schema::create('videos', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('title');
$table->timestamps();
});
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->uuidMorphs('categorizable');
$table->timestamps();
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Nullable morphTo
For the case of a morphTo
relation, you can use the nullable
keyword to allow absent parents.
models:
Image:
imageable: morphTo nullable
2
3
/**
* @propery-read \App\Models\Post|null
*/
class Image extends Model
{
public function imageable()
{
return $this->morphsTo();
}
}
2
3
4
5
6
7
8
9
10
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->nullableMorphs('imageable');
});
2
3
4