Атрибут touches
Атрибут touches в моделях Laravel определяет, какие
родительские модели должны автоматически обновлять свои
временные метки (updated_at) при сохранении
или удалении дочерней модели. Он задаётся в виде массива
строк, содержащих имена методов отношений, которые
ведут к родительским моделям.
Когда дочерняя модель сохраняется, обновляется или удаляется,
Laravel автоматически вызывает метод touch для всех
родительских моделей, перечисленных в атрибуте
touches. Это приводит к обновлению поля
updated_at родительской модели без необходимости
ручного вызова метода touch.
Синтаксис
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class ChildModel extends Model
{
protected $touches = ['parent', 'anotherParent'];
}
?>
Пример
Рассмотрим две модели: Post и Comment.
Каждый комментарий принадлежит одному посту.
Мы хотим, чтобы при добавлении или обновлении комментария
автоматически обновлялась временная метка поста:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
?>
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Comment extends Model
{
protected $touches = ['post'];
public function post()
{
return $this->belongsTo(Post::class);
}
}
?>
Теперь при создании нового комментария к посту:
<?php
namespace AppHttpControllers;
use AppModelsComment;
use AppModelsPost;
use IlluminateHttpRequest;
class CommentController extends Controller
{
public function store(Request $request)
{
$post = Post::find(1);
$comment = new Comment();
$comment->body = 'New comment';
$post->comments()->save($comment);
$res = $post->fresh()->updated_at;
echo $res;
}
}
?>
Результат выполнения кода:
"2024-01-15 14:30:00"
Как видите, поле updated_at поста автоматически
обновилось до текущего времени, хотя мы не вызывали
метод touch явно.
Пример
Атрибут touches также работает при удалении
дочерней модели. Это полезно, когда нужно отслеживать
активность родительской модели на основе наличия
связанных записей:
<?php
namespace AppHttpControllers;
use AppModelsComment;
use AppModelsPost;
class CommentController extends Controller
{
public function destroy($id)
{
$comment = Comment::find($id);
$post = $comment->post;
$oldUpdatedAt = $post->updated_at;
$comment->delete();
$post->refresh();
$res = [
'old' => $oldUpdatedAt,
'new' => $post->updated_at
];
echo json_encode($res);
}
}
?>
Результат выполнения кода:
{"old":"2024-01-15 14:30:00","new":"2024-01-15 14:45:00"}
Пример
Модель может отслеживать несколько родительских моделей. Например, комментарий может принадлежать как посту, так и пользователю, который его оставил:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Comment extends Model
{
protected $touches = ['post', 'user'];
public function post()
{
return $this->belongsTo(Post::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
?>
Теперь при создании комментария будут обновлены временные метки как поста, так и пользователя:
<?php
namespace AppHttpControllers;
use AppModelsComment;
use AppModelsPost;
use AppModelsUser;
use IlluminateHttpRequest;
class CommentController extends Controller
{
public function store(Request $request)
{
$post = Post::find(1);
$user = User::find(1);
$comment = new Comment();
$comment->body = 'Another comment';
$comment->user()->associate($user);
$post->comments()->save($comment);
$res = [
'post_updated' => $post->fresh()->updated_at,
'user_updated' => $user->fresh()->updated_at
];
echo json_encode($res);
}
}
?>
Результат выполнения кода:
{"post_updated":"2024-01-15 15:00:00","user_updated":"2024-01-15 15:00:00"}
Смотрите также
-
атрибут
timestamps,
который управляет автоматическим обновлением временных меток модели -
метод
touch,
который вручную обновляет временные метки модели -
метод
update,
который обновляет модель с триггерами событий -
метод
save,
который сохраняет модель с триггерами событий