По дефолту в моделях Eloquent предполагается, что в таблице есть поля меток времени (timestamp) — created_at
и updated_at
. И с ними можно сделать много чего, настраивая их и выполняя интересные операций. Давайте посмотрим.
1. Отключение меток времени
Если ваша таблица не имеет этих полей, и вы попытаетесь сделать что-то типа Model::create($arrayOfValues);
— вы получите SQL ошибку. Laravel попытается автоматически заполнить поля created_at
/updated_at
и не найдет их.
Чтобы отключить автоматические метки времени, в вашей модели необходимо добавить одно свойство:
class Role extends Model { public $timestamps = FALSE; // ... другие свойства и методы модели }
2. Изменение названия полей меток времени
Что если вы работаете с базой данных, отличной от Laravel, и ваши поля меток времени имеют другие имена? Например, у вас есть create_time
и update_time
. К счастью, вы можете указать их и в модели:
class Role extends Model { const CREATED_AT = 'create_time'; const UPDATED_AT = 'update_time';
3. Изменить формат меток времени
Здесь я просто процитирую официальную документацию Laravel:
По дефолту метки времени имеют формат 'Y-m-d H:i:s'
. Если вам нужен свой, то установите свойство $dateFormat
в вашей модели. Это свойство определяет, как даты хранятся в базе данных, а также их формат при сериализации модели в массив или JSON:
class Flight extends Model { /** * Формат хранения поля даты модели * * @var string */ protected $dateFormat = 'U'; }
4. Многие ко многим: сводная таблица с метками времени
Исключением для автоматизации отметок времени является случай, когда вы создаете сводную таблицу в отношениях «многие ко многим», например, таблица role_user
между таблицами пользователей и ролями.
В модели вы определяете отношения следующим образом:
class User extends Model { public function roles() { return $this->belongsToMany(Role::class); } }
И затем, когда нужно добавить роль пользователю, вы должны сделать что-то вроде этого:
$roleID = 1; $user->roles()->attach($roleID);
По умолчанию сводные таблицы не содержат меток времени. И, в этом случае, Laravel не пытается заполнить поля created_at
/updated_at
.
Но если вы хотите сохранять автоматически метки времени, то вам нужно добавить их в файл миграции, а затем определить отношения, используя ->withTimestamps()
;
public function roles() { return $this->belongsToMany(Role::class)->withTimestamps(); }
5. Сортировка меток времени через latest() и oldest()
Существует два «ярлыка» для сортировки данных по меткам времени.
Вместо:
User::orderBy('created_at', 'desc')->get();
Можно сделать быстрее:
User::latest()->get();
По умолчанию функция latest()
будет сортировать по полю created_at
.
Существует противоположный метод oldest()
, который сортирует created_at
по возрастанию.
User::oldest()->get();
Также вы можете указать другой столбец для сортировки. Например, если вы хотите использовать updated_at
, то можно сделать так:
$lastUpdatedUser = User::newest('updated_at')->first();
6. Обновление без updated_at
Каждый раз, когда вы обновляете запись Eloquent, она автоматически сохраняет текущую метку времени в поле updated_at
, и это крутая фишка.
Но иногда нужно избежать этого, например, вы увеличиваете какое-то значение и не хотите рассматривать это как «полное обновление записи».
Значит вам нужно сделать то же, что и выше — отключить метки времени, но только для этой операции:
$user = User::find(1); $user->profile_views_count = 123; $user->timestamps = false; $user->save();
7. Привязка и Родительская привязка
В противоположность последнему примеру — может быть, вы хотите установить новое значение ТОЛЬКО для поля updated_at
, не меняя другие.
Итак, вместо:
$user->update(['updated_at' => now()]);
Вы можете использовать более короткий метод:
$user->touch();
Другой случай — иногда нужно обновить не только updated_at
текущей модели Eloquent, но и родительскую запись в отношениях.
Например, если какой-либо comment
был обновлен, то вы должны учитывать, что у post
тоже нужно обновить updated_at
.
Значит нужно определить «родительскую привязку» моделей в модели Eloquent:
class Comment extends Model { protected $touches = ['post']; public function post() { return $this->belongsTo('Post'); } }
8. Поля меток времени автоматически Carbon’изированы
Последний «бонусный» совет — скорее даже напоминание, потому что вы должны знать об этом.
По умолчанию, и created_at
и updated_at
преобразуются в $dates
модели Eloquent, поэтому вы можете выполнять над ними Carbon-операции без преобразования в экземпляр Carbon.
Например:
$user->created_at->addDays(3); now()->diffInDays($user->updated_at);
Вот и все, короткие, но, надеюсь, полезные советы!
Автор: Povilas Korop
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.