Railsの情報サイトです。Railsでも複合キーを持つテーブルを扱うWebアプリケーションを構築できそうであることを示しました。前々回と前回で前提としたデータベーステーブルは、文字列や整数値を組み合わせて主キーとしているという特徴がありました。今回は「期間」を用いてレコードを特定するタイプのテーブルをRailsでどう扱うか、というテーマで書きます。「期間でレコードを特定する」とは「期間でレコードを特定する」とはどういうことでしょうか。言葉で説明すると長くなるので、ソースコードで示しましょう。第1回で作成したdb/migrate/...create_departments.rbを次のように修正してください。いう期間でレコードを特定します。このdepartmentsテーブルは、たとえば会社の「部門」を表しています。会社というのは組織改編がありますから、部門の名前その他の属性がいろいろと変わりますね。2000年に「ロボット製造部」ができて、2001年に「ロボット事業部」になり、また2002年から「ロボット事業本部」になった、みたいなことです。この状況をRubyコードで表現すれば、次のようになります。"ロボット事業部"のような感じで事業部を特定できるはずです。2001年8月1日に存在していたのは2番目に作ったオブジェクトです。DurationLimitedモジュールは、あとで作ります。「期間」による関連づけ製品(product)についても同様にコードと期間で特定できるようにしましょう。db/migrate/...create_products.rbを次のように修正してください。ended_onカラムを追加しています。この製品が所属する部門を参照するためにdepartment_codeカラムとdepartment_seq_numberカラムを持っていましたが、department_seq_numberカラムは不要です。ある日付におけるある製品のレコードを取得したとして、それと関連づけられる部門は部門コードとその日付で特定できるからです。次のようなRubyコードで表現される2つの製品(いずれも製品コードは"bob")を考えます。nil)これに関して、次のような操作ができるといいですね。1準備作業いろいろと調べた結果、このような「期間」を利用してレコードを特定するタイプのデータベースを扱うのにGemライブラリcomposite_primary_keysは向いていないようなので、今回は外してしまいます。次の行を除去してください。5.0.4"それから、app/models/department.rbの中身を空にしてください。ActiveRecord::Baseend同様に、app/models/product.rbの中身を空にしてください。ActiveRecord::Baseendそして、マイグレーションをやり直します。db:migrate:resetRSpecによる試験コードここからはテスト駆動開発のやり方で行きましょう。RSpecのコードを書きます。次のように書き換えます。次のように書き換えます。実装開始さあ、実装開始です。何はともあれ、RSpecを動かしてみましょう。failure定数DurationLimitedが未定義だと言っていますね。新規ファイルapp/models/duration_limited.rbを次のような内容で作成してください。failureまあ、想定通りです。途中経過は除いて、findメソッドを実装してしまいます。app/models/duration_limited.rbを次のように修正します。読者の方からの指摘を受けて、ソースコードの一部を修正しました。条件をそのままにしてended_onカラムの値を「2001-01-01」から「2000-12-31」に直す、という対処法もありますが、私は条件式を修正する方がいいと思います。確かにended_onカラムの意味は「終了日」なので、日常的な感覚では「2000-12-31」がふさわしいかもしれません。Date型をDateTime型のサブセットと考えると、「2000-12-31」という日付は2000年12月31日の00時00分00秒と同じであるとみなせます。2001年1月1日から部門の名前が変わるとすれば、2000年12月31日の23時59分59秒においては、前の部門の名前が有効であるべきです。DurationLimited.current_dateが常にDate型であると仮定すればどちらの方法でも結果は同じですが、条件式を修正する方が厳密です。「終了日」を人に向けて画面表示する際には前日の日付に直す必要があります。(2012/03/28)続いて、app/models/department.rbを次のように修正します。failures望んだ仕様通りのfindメソッドができました。次回は、部門と製品間の関連づけについて書く予定です。