typusの我流運用法!!

実際に、railsの管理画面系gemとして、typusを選択して、四年ほど運用してきた時のノウハウ集です。

インストール時に発生する基本的な項目は[rails管理画面作成gem:typusのカスタマイズ方法tips集](http://qiita.com/baban/items/1d13778532e13f492f89)にまとめてありますので、今回はそこを超えた項目のカスタマイズ方法を紹介させていただきます。

## そもそも何でtypusを選択したの？

「これが一番カスタマイズが効くから」

この一言で説明できるのですが、もう少し詳しく実例を出しましょう。

以前、ゲームを作る会社で管理画面を作っていたのですが
最初バイト君が作った管理画面だと、すべてのモデルに対してscaffoldを行って、合わせてviewを開発していたのですが、日々変わるテーブル構成にバイトの子の出社日数では全然変更が追いつかないで、リリースまでに動かない画面が頻繁に発生しました。
実際には、コントローラーではなく、viewで、テキストって自明なカラムに以下の様な決まりきったコードが散乱していました。

```
<%=f.text_field :nickname %>
```

管理画面は見た目にあまり工数を割く必要はないので、カラムのデータ型がstringであればそもそもこういうのを毎回書くのは手間ですし、開発中にカラムの名前や型が変更するのはリリース前はしょっちゅうでしたから毎度調べて合わせるのは大変です。

なので、自分が携わった時にはこういうコードを毎度書き散らすよりは、モデルの中からカラムの情報を取り出して画面を自動で生成する様なメタプログラムを行って、viewのカスタマイズがどうしても必要な画面以外は生産性、メンテナンス性を上げて一定の成功をしたのですが

ですが、作った後に

「これって、表示したいカラムが何かとか、並び順とか、設定ファイルに書いたら自動生成してくれる方がいいんじゃないか？、というか既にそういうgemがあるんじゃないか？」

そう思って、探し出したのがtypusとの出会いでした。

開発者しか使わない場面ではRailsAdminは便利なGemなのですが、この自由度のものを企画側には触らせられないですし、かといって

経験上のユーザーの検索機能に関しては、かなり多様な方法を求められるのを知っていた。

例えば

* Facebook ID、Twitter ID、ニックネームでユーザーを検索したい
* 入会日時、退会日時で絞り込みさせて
* 要注意ユーザーの場合、一覧画面では赤色で表示して

こうなってくると、FacebookIDなどはユーザーテーブルには普通は含めないですし、日時の絞り込みは、入力方式をどうするかで要求は変わりますし、結局DSLで表現できる範囲をあっさり超えてしまうんですよね。

マスターデータの、CRUDならDSLで十分でしょうけど
それだけではないものを扱う以上、基本カスタマイズできないという道具ではだめだろう、という経験からtypusを採用しました。

動くようになるまでも、[別記事](http://qiita.com/baban/items/1d13778532e13f492f89)で書きました。

また、ツールとして完成しているとは言えないので、typus自体への[恨み節](http://qiita.com/baban/items/bfb6f136bd444b142652)も以前記事にしましたが、今回はまずはノウハウ集という感じの記事。

## ymlファイルの編集

### カテゴリ分類

しばらく、使ってきたの感想ですが最初YAMLファイルを一括生成してからの設定ですが

以下の手順でやっていくと間違いがなくて効率的です。

まず、yamlファイルを用途に分けて、その用途に分けて設定に規則を設けます。
管理画面でそのコンテンツがどう使われるかどうかを予想するのは、正直大変で時間もかかりますが
大半の画面はさほどのカスタマイズも必要としていません。
実際Railsを使っていると、じっくり仕様を検討して開発する事も少ないと思います。

ですので、このコンテンツがどういう扱いをされるか考えて、以下のどの分類に属しているかを考えて、そのあとはそれぞれの規則に沿って設定を行います。

最初はこれで運用をして、そのあと案件が安定して管理画面の改修が必要になったタイミングで運用がわの意見を集めてカスタマイズを行なっていくくらいで大体の案件では良いのではないかと思います。

コンテンツ的には以下の４種類

* 配信コンテンツ
* マスターデータ
* ログ
* その他

| 種類 | 説明 | applicationの表示名 |
|---|---|---|
| 配信コンテンツ | コラムなどのコンテンツ配信側が日々作成するデータ | Contents, 100|
| マスターデータ | カテゴリの名前とIDなど、管理側で使うあまり変更を行わないデータ | Master, 200 |
| ログ | ユーザーが動作を行うたびに生成される、日々の動作の記録。お問い合わせや、データ解析などのために参照する | Log, 300 | 

このうち、どのデータに入るかを分類することで、コンテンツのアクセス権限や並び順や、ダッシュボードでの表示位置は、７割くらいのテーブルで十分な完成度になります。

### 配信コンテンツ

* idの昇順でデータを並べる
* コンテンツを作成する人か、管理者が変更権限を持っている。他の人は閲覧権限のみ持っている

```yaml
Column:
  fields:
    default: title, content, public, start_at, end_at, category_id
    list: id, title, content, public, start_at, end_at, category_id
    form: title, content, public, start_at, end_at, category_id
    options:
      selectors: category_id
      booleans:
        public: ["公開", "非公開"]
  relationships: user_upload_images, user_upload_movie
  filters: public, category_id
  search: title, content
  application: Contents, 100
  order_by: -id
```

### マスターデータ

* idの降順でデータは並んでいる
* 管理者しかデータは編集できない

```yaml
CategoryMaster:
  fields:
    default: name, description, publiced
    list: id, name, description, publiced
    form: name, description, publiced
    options:
      booleans:
        publiced: ["公開", "非公開"]
  application: Master, 300
  search: name, description
```

### ログ

* idの昇順でデータは並んでいる
* 誰もデータは編集しない

```yaml
Bookmark:
  fields:
    default: parent_id, user_id
    list: id, parent_id, user_id
  relationships:
  application: Log,300
  order_by: -id
```

### listとformの表示分け

ymlファイルには、defaultに表示したい項目を

* idの表示は、listの項目だけに追加しておく
* formに表示する項目は、一覧に表示する項目をすべて持っている

### 不要な項目をダッシュボードから消す

小技ですが、ダッシュボードには表示させるつもりのないモデルは、yamlファイルのアプリケーションの行を消すと、ダッシュボードには表示されなくなるので、便利ですよ。

## 統計画面を追加

統計画面は`Admin::ResourcesController`ではなく`Admin::BaseController`を継承してアクセス権限だけを借りれば管理画面で扱える統計画面に入れられます。

そもそもサイドバーに標準で好きなものを入れられる様に隙間を入れているので、普段からそこに統計項目を入れていますね。