Laravel
Eloquent
ORM
提供了数据模型关联表操作的 API,熟练掌握这些API后,才体会到 Laravel
数据库操作有多高效。
一、hasMany 一对多关联
save/saveMany 创建关联记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $comment = new Comment(['message' => 'A new comment.']); $post = Post::find(1); $post->comments()->save($comment);
$post->comments()->saveMany([ new Comment(['message' => 'A new comment.']), new Comment(['message' => 'Another new comment.']), ]);
$post->refresh();
$post->comments;
|
create/createMany 创建关联记录
和 save/saveMany
的区别是参数时数组,而不是模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| use App\Models\Post;
$post = Post::find(1);
$comment = $post->comments()->create([ 'message' => 'A new comment.', ]);
$post = Post::find(1);
$post->comments()->createMany([ ['message' => 'A new comment.'], ['message' => 'Another new comment.'], ]);
|
push 递归保存模型和关联数据
保持模型同时,保存其关联数据。
例:保存 Post
模型及其评论和评论作者
1 2 3 4 5 6
| $post = Post::find(1);
$post->comments[0]->message = 'Message'; $post->comments[0]->author->name = 'Author Name';
$post->push();
|
二、Belongs To (一对多反向)属于关联
1 2 3 4 5 6 7 8 9 10 11 12
| use App\Models\Account;
$account = Account::find(10);
$user->account()->associate($account);
$user->account()->dissociate();
$user->save();
|
三、多对多关联
attach 创建多对多关联记录
用于新建时。
1 2 3 4 5 6 7 8 9 10
| $user->roles()->attach($roleId); $user->roles()->attach([1, 2, 3]);
$user->roles()->attach($roleId, ['expires' => $expires]); $user->roles()->attach([1 => ['expires' => $expires], 2, 3]); $user->roles()->attach([ 1 => ['expires' => $expires], 2 => ['expires' => $expires], ]);
|
detach 删除中间表关联记录
用于删除时。
1 2 3 4 5 6 7 8
| $user->roles()->detach($roleId);
$user->roles()->detach([1, 2, 3]);
$user->roles()->detach();
|
sync 同步关联
用于修改模型时。
中间表记录中,所有未在 ID 数组中的记录都将会被移除,在数组中的可更新。
1 2 3 4 5 6 7 8 9
| $user->roles()->sync([1, 2, 3]); $user->roles()->sync([1 => ['expires' => true], 2, 3]);
$user->roles()->syncWithPivotValues([1, 2, 3], ['active' => true]);
$user->roles()->syncWithoutDetaching([1, 2, 3]);
|
toggle 切换关联
关联表中有则删除,无则新建。
1
| $user->roles()->toggle([1, 2, 3]);
|
四、更新父级时间戳
当一个模型属 belongsTo
或者 belongsToMany
另一个模型时, 例如 Comment
属于 Post
,当 Comment
模型被更新时,你需要自动「触发」父级 Post
模型的 updated_at
时间戳的更新。Eloquent
让它变得简单,只要在子模型加一个包含关联名称的 touches
属性即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model {
protected $touches = ['post'];
public function post() { return $this->belongsTo(Post::class); } }
|
参考
Laravel 9 中文文档