リソースとテーブルのギャップを飛び越える

2010年10月20日(水)
川尻 剛

テーブル・ビューで実現する

複数のテーブルを参照するSQLの機能として、誰もが思いつくのは、テーブル・ビューです。幸い、ActiveRecordでは、対応するデータがテーブル・ビューであっても、通常通りに動作します。ここでは、販売に対するテーブル・ビューを作成して、それに対応するActiveRecordクラスを定義してみます。

テーブル・ビューは、コンソール上でも作成できますが、Migrationからでも作成できます。次のように、executeメソッドで指定することで作成できます*1

  • [*1] ただし、executeでは、schema.rb(現在のテーブル構成を記録するもの)には反映されません。テスト実行時には工夫が必要です。

あとは、作成したテーブル・ビュー(shop_sales)に対応するActiveRecordを、ほかのモデルと同じ手順で定義するだけです。ただし、保存処理は、独自に定義する必要があります。保存処理の実装例を、次に示します。

保存処理は、トランザクションを使用し、失敗した時にロール・バックするようにしました。

ここで、論理モデルの話からは少し離れますが、名前空間について補足しておきます。上記のコードは、次の図4に示すように、modelsディレクトリに分けて配置しています。

図4: 各ファイルの配置

shopで分けた理由は、モデル名の重複を避けることと、分離しやすくすることです。例えば、Shop以下をプラグイン化して再利用する場合、Shop以外のコンポーネントからは、次のように、モジュール付きで呼び出す必要があります。これにより、コード上から依存関係を見つけやすくなります。

同様の理由から、テーブル名にもshopという接頭語を付けて定義します。これは、上記のコードにあるように、table_name_prefixメソッドを使用することによって自動的に、テーブル名に付加されてマッピングされます。これらは、一般的によく使われるテクニックなので、覚えておくと良いでしょう。

さらに、今回は、実テーブルに対応するモデルをphysicalディレクトリに配置し、テーブル・ビューに対応するモデルをtable_viewディレクトリに配置しました。これは、使えるAPIが双方で一部異なることを、モジュール名の違いによって開発者に示す狙いがあります。

それでは、定義したモデルを、コンソールから操作してみましょう。

コントローラ側で呼び出すような処理が、正常に動作していることが分かります。scaffoldが生成するような、シンプルで美しいコントローラを実装できそうです。また、販売に関連するロジックも、ほかのモデルから分離させて、本クラスに集約できそうです。

株式会社日立ソリューションズ

技術開発本部 Rubyセンタ所属
1977年生まれ。入社後、自社フレームワークの開発を経てRIAの調査などに関わる。
最近は「お客様とチームがより幸せなるマネジメント」を目標としてプロジェクトマネジメントを勉強中。著書に「Java開発者のためのAjax実践開発入門」(共著)など。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています