Symfony5 x DoctrineでcreatedAt / updatedAtを自動設定
ほとんど Doctrine2の小ネタ(データベースからエンティティを作る&エンティティの継承編) に記載されている内容と同じだけど、該当記事は公開日が 2014.11.20 なので Symfony 5 でもこれで動きます、というのを書きます。確認したSymfonyのバージョンはv5.1.5。
/**
* @ORM\Entity(repositoryClass=FooRepository::class)
* @ORM\HasLifecycleCallbacks
*/
class Foo
{
まず、classの宣言の部分に @ORM\HasLifecycleCallbacks
アノテーションを追加。
次に、メソッドとして以下を追加。
/**
* @ORM\PrePersist
*/
public function setCreatedAtValue()
{
$this->createdAt = new \DateTimeImmutable();
$this->updatedAt = new \DateTimeImmutable();
}
/**
* @ORM\PreUpdate
*/
public function setUpdatedAtValue()
{
$this->updatedAt = new \DateTimeImmutable();
}
setCreatedAtValue()
で updatedAt
を更新するのが命名的に気持ち悪ければ setUpdatedAtValue()
を別メソッドで用意してもOK。
簡単な動作の説明。
@ORM\HasLifecycleCallbacks
アノテーションがあるとDoctrineはこのEntityにlifecycle callbackが存在していると認識する。これがないと @ORM\PrePersist
や @ORM\PreUpdate
は呼び出されないので注意。
@ORM\PrePersist
はpersistが実行される前(INSERT前)に呼び出されるので、ここで createdAt
と updatedAt
に現在日時を入れる。
@ORM\PreUpdate
は更新される前(UPDATE前)に呼び出されるので、ここで updatedAt
に現在日時を入れる。
昔のSymfonyのドキュメントだとTimestampableが一押しだったけれど、Symfony 5でTimestampableはうまく動かないし、無駄に複雑なので、潔くDoctrineのライフサイクルを使った方が良いです。
2021/08/14 追記
Symfony v5.3.6 で make:entity するとtypeのデフォルトが datetime_immutable
になっているので、上記の例を \DateTime
から \DateTimeImmutable
に修正しました。
Discussion