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