CRUDっぽいルーティングとアクションを追加できるTraitコントローラーを作ってみた

管理画面で欲しいCRUD処理

いわゆる管理画面作ってると CRUDができるAdmin Gegeneratorっぽいものが欲しくなりますよね。
色々アプローチはあると思います。

  • テンプレートからひな形のコードを生成してしまう Generetor 方式
    • 必要があれば直接編集したり、直接編集しない場合はカスケード機能みたいなものがあったり
    • Symfony だと `generate:doctrine:crud` コマンドっぽいの
  • ymlなどで定義を書けばDSLで管理画面っぽいCRUDをある程度好きにできる方式

そして、これらはWebアプリケーションフレームワークが標準で用意していたり、別途ライブラリ(バンドル)を入れたりすることで実現可能だったりします。

個人的に、完全generateの場合は再generateすると死ねるので、「最初の一発だけ生成させて後は頑張る」になりますし、必要以上に生成されるコードが多すぎたりするのであまり選択したくありません。

ymlで定義できる方式は「DSLで表現できるかぎりは良いけど、複雑なものは無理ゲー」なので積極的に使いたいとは思えません。

というわけで、「おれがかんがえたミニマムなCRUDバンドル」が今回のお話です。

普通のコントローラークラスにTraitで CRUDなルーティングと機能が生える

出落ちですが、そういうことです。
Symfony2のバンドルとして作りました。
Traitを使うというのと、array()は[]で書いてるので、PHP5.4以上じゃないと動きません。
まさか、今どき5.3でry

Traitに慣れていないという方は下記の記事あたりを読んでみてください。
ちょっと語弊ありそうですが、「クラスに機能(メソッド)があたかも最初からあったかのように追加できる」ものです。
scalaのTraitと名前は一緒ですが、できることが違うのでそれはそれで注意が必要だったりします。


つまり方向性としては

  • 既に用意しているコントローラークラスに Trait を use するだけで CRUDな機能を追加できる。です。

つまり、自動生成する部分はありません。Traitで書かれたとおりにしかデフォルトでは動きません。
シンプルですね。

@Crud アノテーションで Entity, Repository, 各テンプレートファイルを指定

とはいえ、どの Entity をどの Repository を使ってどのテンプレートファイルで。というのは指定する必要があります。
Traitなので既存のコントローラークラスにプロパティを生やすことも考えたのですが、Trait を使わなくなったときに use 行を削除するだけでなく無駄なプロパティも削除する必要があるので、今回は Doctrine にあるアノテーション Reader を使ってこれらを書けるようにしました。CRUD機能が要らなくなったらuseを外せばアノテーションは残るけど無視されるだけなんでまだましかなと。(ちょっと微妙な感はあります)


最終的な利用方法は以下のような感じ

<?php
namespace Brtriver\SimpleCrudBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

use Brtriver\SimpleCrudBundle\Controller\SimpleCrudTraitController;
use Brtriver\SimpleCrudBundle\Annotation\Crud;

/**
 * @Route("/simple_crud", name="simple_crud_demo")
 * @Crud(
 *   entity="Brtriver\SimpleCrudBundle\Entity\Demo",
 *   repository="BrtriverSimpleCrudBundle:Demo",
 *   template_list="BrtriverSimpleCrudBundle:Demo:list.html.twig",
 *   template_new="BrtriverSimpleCrudBundle:Demo:new.html.twig",
 *   template_edit="BrtriverSimpleCrudBundle:Demo:edit.html.twig",
 *   template_show="BrtriverSimpleCrudBundle:Demo:show.html.twig",
 *   form="Brtriver\SimpleCrudBundle\Form\DemoType"
 * )
 */
class DemoController extends Controller
{
    use SimpleCrudTraitController;

    ....

動きを変えたいとき

テンプレートなんかは何も書かれていないのに等しいのでがんばって好きなように書いて指定してください。
アクションメソッドはTrait なので、Traitクラスに書かれたメソッドと同じメソッドを自分のコントローラーで定義すればおk。

install 方法や詳しいことは?

github の README 参照。
GitHub - brtriver/simple-crud-bundle: simple crud actions method by trait for Symfony2

わかったこと

  • CRUDのためだけに BaseCrudController みたいなの作ると辛いよね
  • CRUD っていいながら Delete 作ってないことに気づいた
  • Annotation がこんなに簡単に使えるとは知らなかった
  • オレオレ Trait 作って利用すると色々幸せになれる場面は多そう