[Symfony] EasyAdminBundleがjson DBAL Typeの配列プロパティを出力してくれない問題
エンティティのプロパティの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の この辺りのコード で json
も json_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を細かく設定してあげる必要がある
Discussion