🎻

[Symfony] EasyAdminBundleがjson DBAL Typeの配列プロパティを出力してくれない問題

2020/04/20に公開

エンティティのプロパティのDBAL Typeを json にしているとEasyAdminBundleが自動でそのプロパティを処理してくれないことに気づいたのでメモです。

どういうこと?

EasyAdminBundleは、多くの場合何も考えずに

easy_admin:
  entities:
      - App\Entity\Foo
      - App\Entity\Bar
      - App\Entity\Baz

って感じで設定しておけば、エンティティのプロパティのデータ型を勝手に推測して適切にCRUDの画面を表示してくれます。

が、DBAL Typeが json のプロパティはデフォルトでは無視される仕様になっているため、配列を入れるプロパティを json DBAL Typeで作っていると、その項目がEasyAdminBundleの管理画面に表示されなくて困ることになります。

今回この問題に気づいたのは、MakerBundle で作ったUserエンティティの $roles プロパティが json DBAL Typeになっていたためです。

$ bin/console make:user

でUserエンティティを作ると、デフォルトで $roles プロパティが json DBAL Typeで作成されます。

/**
 * @ORM\Column(type="json")
 */
private $roles = [];

この状態でEasyAdminBundleを

easy_admin:
  entities:
      - App\Entity\User

とだけ設定しても、 $roles プロパティが表示されないことになります。

ちなみに、EasyAdminBundleの この辺りのコードjsonjson_array も除外されているっぽいです。

json DBAL TypeはDoctrine的には配列なので 普通に配列として扱ってくれてもよさそうなんですが…🤔

解決策1

ともかく、 json DBAL Typeではなく array DBAL Typeを使えばすぐに解決できます。

/**
- * @ORM\Column(type="json")
+ * @ORM\Column(type="array")
 */
private $roles = [];
$ bin/console doctrine:migrations:diff
$ bin/console doctrine:migrations:migrate

もしすでにjson型式のデータが入っている場合は、マイグレーションでカラムの型だけを変更しても、中に入っているデータがjson型式だとアプリでunserializeしようとしてエラーになってしまうので、データの更新のためのマイグレーションも書く必要があります。

Doctrine Migrationsでデータ更新のマイグレーションを手動で書く方法については こちらの記事 をご参照ください。

解決策2

どうしても json DBAL Typeのままで行きたい場合は、EasyAdminBundleを「お任せ」で使うのではなく、自分で細かく設定してあげる必要があります。

easy_admin:
  entities:
    User:
      class: App\Entity\User
      list:
        fields:
          - { property: email, type: email }
          - { property: roles, type: array }
      form:
        fields:
          - { property: email, type: email }
          - { property: password, type: text }
          - { property: roles, type: collection }

こんな感じで、一覧画面と作成・編集画面それぞれについて、どのプロパティをどのタイプで出力するかを全部設定してあげればOKです。

まとめ

  • EasyAdminBundleは、 json DBAL Typeのプロパティを自動で表示してくれない
  • DBAL Typeを array に変更するか、easy_admin.yamlを細かく設定してあげる必要がある
GitHubで編集を提案

Discussion