ActiveScaffold、複数モデルを増やしてもできるだけ共通ビューの編集で済ませる その1

ActiveScaffold、複数モデルを増やしてもできるだけ共通ビューの編集で済ませる その1

今回はRailsの話。
あるWeb+DBシステムで扱われるデータベース内の全テーブルに対して、Rails+ActiveScaffoldでテーブル内容検索・閲覧・CSV出力画面をぱぱぱっとお手軽に作る必要がでました。
単純にそれを

  1. テーブルを1つ追加
  2. モデルも1つ追加
  3. ビューも1つ追加…

などとやると、さして機能が変わらないけどソースが派生して増え続けてしまう。
最悪派生コピーを許すとしても、コピーした後で手を入れる箇所ができるだけ少なく出来たほうが効率が良い。
ということで、まず手始めに「コントローラが増え続けても ビューは極力共通」で書く方法を検討します。

Railsは1.2.5、編集環境はAptana Studio1.2.1です。
ActiveScaffoldのプラグインは導入済みの状態から開始。
db:migrationも、モデル作成も一通り終わった状態からです。

Personモデル(person_controller.rb)のデフォルト内容
class PersonController < ApplicationController
  active_scaffold :person
  layout "layout"
end

layout行で、Personモデルには"layout"→layout.rhtmlファイルがビューとして参照される設定になっています。
デフォルトではどのコントローラでも同じのようです。

ビュー layout.rhtml のデフォルト内容
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; utf8" />
        <title>閲覧ページ</title>
        <%= javascript_include_tag :defaults %>
        <%= active_scaffold_includes %>
    </head>
    <body>
        <%= yield %>
    </body>
</html>

デフォルトのlayout.rhtml の内容はいたってシンプル。ここから表現を増やしてみます。
私が最初に気に入らなかったのはtitleタグが"閲覧ページ"で文言固定で気が利いてない点。
これを、どのモデルに対応したビュー(閲覧ページ)で、どのアクションの処理結果で表示されたのかを追加してみます。
以下の行に対して、

        <title>閲覧ページ</title>

controllerオブジェクトの情報を埋め込んで表示させます。

        <title> <%= controller.controller_name %> 閲覧ページ <%= controller.action_name %></title>

ビューの中で参照して利用できるオブジェクトは、まず

  1. コントローラ側でアクションが実行された際に作成されたインスタンス変数(@personに格納したりする)
  2. 各種ヘルパーメソッド

が主なものですが、それ以外にも環境情報として以下が利用できます。

  • prams
  • flash
  • session
  • hedders
  • response
  • request
  • logger
  • controller

今回はさらにflashも合わせて、以下の内容でlayout.rhtmlを保存しました。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; utf8" />
        <title> <%= controller.controller_name %> 閲覧ページ <%= controller.action_name %></title>
        <%= javascript_include_tag :defaults %>
        <%= active_scaffold_includes %>
    </head>
    <body>
        <p style="color: green" id="flashbox">
            <%= flash[:notice] %>
        </p>
        <p>
            <a href="/">トップページに戻る</a>
        </p>
        <%= yield %>
    </body>
</html>

これで例えば、/person/ にアクセスするとページのタイトルが"person 閲覧ページ index"となります。
アクションを入れるのは好みでしょうか。