Has One or Many
You can do effortless has-one or has-many relations both ways with just issuing the type, following Laravel naming conventions.
In this example, Larawiz gets a hint of the model you want to reach using the relation name:
- In the
User
model, thepost: hasMany
means it has manyPost
- In the
Post
andBiography
models, theuser: belongsTo
means it belongs to anUser
.
The result is all models and migrations relations in sync.
models:
User:
name: string
posts: hasMany
biography: hasOne
Post:
title: string
body: longText
user: belongsTo
Biography:
body: longText
user: belongsTo
2
3
4
5
6
7
8
9
10
11
12
13
14
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
public function biography()
{
return $this->hasOne(Biography::class);
}
}
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
class Biography extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
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
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->longText('body');
$table->foreignIdFor(User::class);
$table->timestamps();
});
Schema::create('biographies', function (Blueprint $table) {
$table->id();
$table->longText('body');
$table->foreignIdFor(User::class);
$table->timestamps();
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Guessing columns
Larawiz always tries to guess the column to create based the model name plus the primary column, like user_id
or post_title
if you are using custom primary keys.
Indexed and null belongsTo
When creating a belongsTo
relation, you can issue the keyword index
or unique
to create an index or unique index on the relation column, respectively. This can greatly speed up retrieving relations from the parent model, like using unique
for one-to-one relations and index
for one-to-many.
You can also use the nullable
keyword to create a nullable column, which can be used to create models without a belonging parent model, even in combination with index keywords.
models:
User:
name: string
comments: hasMany
Comment:
author: belongsTo:User index nullable withDefault
Biography:
user: belongsTo unique
2
3
4
5
6
7
8
9
10
class Comment extends Model
{
public function comment()
{
return $this->belongsTo(User::class)->withDefault();
}
}
2
3
4
5
6
7
Schema::create('user', function (Blueprint $table) {
$table->id();
$table->string('name');
});
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(User::class)->index()->nullable();
});
Schema::create('biographies', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(User::class)->unique();
});
2
3
4
5
6
7
8
9
10
11
12
13
14
withDefault
is recommended
If you use nullable
in your belongsTo
relation, remember that you can also use withDefault
to return an empty relation instance if the record is not found.
Of Many
For the case of has one of many, you can mix the declaration with latestOfMany
, oldestOfMany
and ofMany
with basic syntax. These methods will be set in the Model, with their respective PHPDoc. These also receive arguments.
Since the most normal name of the relation would be "lastSomething" or "firstSomething", Larawiz will extract the last word and guess the model with it. For example, lastOrder
will point to the Order
model.
models:
Customer:
orders: hasMany
oldestOrder: hasOne oldestOfMany
largestOrder: hasOne ofMany:max,price
Order:
# ...
2
3
4
5
6
7
8
class Customer extends Model
{
public function orders()
{
return $this->hasMany(Order::class);
}
public function oldestOrder()
{
return $this->hasOne(Order::class)->oldestOfMany();
}
public function largestOrder()
{
return $this->hasOne(Order::class)->ofMany('max', 'price');
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17