Продвинутые техники Eloquent
Сравнение моделей
if ($post->is($anotherPost)) {
// та же запись
}
if ($post->isNot($anotherPost)) {
// разные записи
}
Обновление связанных меток времени
Если нужно обновлять updated_at родителя при изменении дочерней модели:
class Comment extends Model
{
protected $touches = ['post'];
public function post()
{
return $this->belongsTo(Post::class);
}
}
Теперь при обновлении комментария обновится и post.updated_at.
Свежие данные
$fresh = $post->fresh(); // новый объект из БД
$post->refresh(); // обновляет текущий объект
Клонирование
$copy = $post->replicate();
$copy->title = 'Копия';
$copy->save();
Условная загрузка
$posts = Post::with(['comments' => function ($query) {
$query->when($request->has('approved'), fn ($q) => $q->where('approved', true));
}])->get();
Chunk и Cursor для больших данных
Post::chunk(200, function ($posts) {
foreach ($posts as $post) {
// обработка
}
});
foreach (Post::cursor() as $post) {
// обработка
}
chunk выполняет несколько запросов, cursor — один. cursor экономит память.
События модели
protected static function booted(): void
{
static::creating(function ($post) {
$post->slug = Str::slug($post->title);
});
static::deleted(function ($post) {
// очистка связанных данных
});
}
События: retrieved, creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored.
Pruning старых записей
Модель может сама удалять старые записи:
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Database\Eloquent\MassPrunable;
class LoginLog extends Model
{
use MassPrunable;
public function prunable()
{
return static::where('created_at', '<=', now()->subDays(30));
}
}
Запуск:
php artisan model:prune