🎻

SymfonyでエンティティをTimestampableにできるDoctrine extensionsに便利なTraitがあった件

2020/04/17に公開

タイトルのとおりなのですが補足も含めて長々と書きます。結論は こちら

Doctrine extensionsとは

Symfonyで、すべてのエンティティに作成日時と更新日時を持たせたいという要件はよくあります。

「作成日時と更新日時を持つ」という振る舞いのことを英語では Timestampable と言ったりします。

symfony timestampable とかでググってみると、Doctrine extensionsTimestampable を使いましょうという情報が出てきます。

Symfonyの公式ドキュメントもDoctrine extensionsにリンクしていますね。
https://symfony.com/doc/current/doctrine.html#doctrine-extensions-timestampable-translatable-etc

Doctrine extensionsは、Doctrine ORM(およびMongoDM ODM)に対して便利な拡張を色々と提供してくれるライブラリです。

この中の一つである Timestampable を使えば簡単にエンティティをTimestampableにできるよということです。

公式ドキュメントのとおり導入してみる

公式ドキュメント によると、gedmo/doctrine-extensions の Timestampable 機能をSymfony4プロジェクトに導入する手順は以下のとおりとのことです。

1. インストールする

composer require gedmo/doctrine-extensions

2. 設定ファイルを作る

services:
  gedmo.listener.timestampable:
    class: Gedmo\Timestampable\TimestampableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [setAnnotationReader, ['@annotation_reader']]

3. エンティティクラスにプロパティとgetter/setterを追加し、プロパティには @Gedmo\Timestampable() アノテーションを付ける

/**
 * @ORM\Column(type="datetime")
 *
 * @Gedmo\Timestampable(on="create")
 *
 * @var \DateTime
 */
private $createdAt;

/**
 * @ORM\Column(type="datetime")
 *
 * @Gedmo\Timestampable(on="update")
 *
 * @var \DateTime
 */
private $updatedAt;

// ...

public function getCreatedAt(): \DateTime
{
    return $this->createdAt;
}

public function setCreatedAt(\DateTime $createdAt): void
{
    $this->createdAt = $createdAt;
}

public function getUpdatedAt(): \DateTime
{
    return $this->updatedAt;
}

public function setUpdatedAt(\DateTime $updatedAt): void
{
    $this->updatedAt = $updatedAt;
}

…え、めちゃくちゃ面倒じゃないですか?😓

特にエンティティにいちいちプロパティとgetter/setterを自分で書かないといけないのがすごく嫌です。適当によろしくやってほしい…

実はプロパティとgetter/setterを追加してくれるTraitがあった

なんと、よく見たら TimestampableEntity とかいうプロパティとgetter/setterを追加してくれるTraitがありました😓

Install Gedmo Doctrine2 extensions in Symfony 4

こっちのドキュメントがTraitに一切触れてなかったのでまったく気付かなかったのですが、

Timestampable behavior extension for Doctrine 2

こっちのTimestampable単体のドキュメントを見ると、最後にちゃんとTraitについて書かれてました。

知ってましたか?知ってましたか。そうですか…。

何にせよ、このTraitを使えばエンティティの変更は

use Gedmo\Timestampable\Traits\TimestampableEntity;

// ...

use TimestampableEntity;

の2行だけでいいので、だいぶ幸せになれます。

余談:Traitの存在を知らなかったのでずっと代わりにknplabs/doctrine-behaviorsを使ってました

ちなみに、僕はアホすぎてTraitの存在に気づいてなかったので、ずっと代わりに knplabs/doctrine-behaviors を使ってました。

こっちはアホな僕でも このドキュメント を見れば

  • TimestampableInterface を実装して
  • TimestampableTrait をuseすれば

それだけでTimestampableになるやん!ということが一目で分かったので、有難がって使ってました😅

まあでもこちらはDoctrine extensionsと違って設定ファイルが不要でエンティティを追記するだけで対応できるので、ちょっとでも楽したい人にはいいかもしれません。

まとめ

  • Doctrine extensionsのTimestampableには便利なTraitがあった
  • ドキュメントはちゃんと隅々まで読もう…
  • knplabs/doctrine-behaviorsも便利だよ
GitHubで編集を提案

Discussion