AWDwR "Chapter15 More Active Record"
もっとActive Record! もっとアップルのiMac G5欲しい!
Act as
DBのデータをリスト構造やツリー構造のように扱うこともできるよ。ステキじゃなーい!
まずリスト構造の場合はテーブルにpositionというカラムを定義してモデルを以下のように定義。
class Parent < ActiveRecord::Base has_many :children, :order => position end class Child < ActiveRecord::Base belongs_to :parent acts_as_list :scope => :parent_id end
そうするとchildrenは以下のようにして扱える。
parent.children[0].name parent.children[0].first? # 先頭? parent.children[2].last? # 最後? parent.children[1].lower_item # 一つ後 parent.children[1].higher_item # 一つ前 parent.children[0].move_lower # 一つ前に移動させる parent.children[2].move_higher # 一つ後に移動させる parent.children[0].move_to_bottom # 最後に移動させる parent.children[2].move_to_top # 先頭に移動させる
ただし操作した後はreloadしとかないとparentはわかってくんないから注意。
次はツリー構造。この場合はテーブルにparent_idというカラムを定義してモデルを以下のように定義。
class Category < ActiveRecord::Base acts_as_tree end
そうすると以下のようにして扱える。
sub = root.children.create sub_sub = sub.children.create sub_sub_sub = sub_sub.children.create root.children.first.name root.children.size root.children.find(:all, ;conditions => "name='Book'") sub.parent.name
Aggregation
複数のクラスからなるモデルのデータを一つのテーブルに格納するのがアグリゲーション。Customerクラスのname属性にNameクラスをマッピングしている場合は
class Customer < ActiveRecord::Base composed_of :name, :class_name => Name, :mapping => [[:first_name, :first], [:last_name, :last]] end
と定義。Nameクラスの属性にアクセスするには
customer.name.first customer.name.last
とする。Nameクラスの属性を変更するには新しいインスタンスを作って属性にセットすること。
customer.name = Name.new(firstname, lastname) customer.save
Single Table Inheritance
継承関係のクラスのオブジェクトを一つのテーブルに格納する単一テーブル継承ってやつね。その場合はテーブルにtypeというカラムを定義して以下のようにモデルを定義する。
class Person < ActiveRecord::Base end class Customer < Person end class Employee < Person end class Manager < Employee end
クラス名はperson.classで取得可能。
Validation
バリデーションはいろいろあるよ。
validate # 保存時に確認 validate_on_create # 新規保存時のみ確認 validate_on_update # 更新時のみ確認 validates_acceptance_of # チェックボックスがチェックされていることを確認(規約の承認などに使うそうな) validates_associated # 関連付けられたオブジェクトも確認 validates_confirmation_of # 確認用の属性と一致しているかどうかを確認(確認用の属性名は_confirmationを付ける。パスワードの登録の確認によく使われるね) validates_each # 複数の属性をブロックを使って確認 validates_exclusion_of # 指定した値のセットに含まれていないことを確認 validates_format_of # 指定した正規表現にマッチすることを確認 validates_inclusion_of # 指定した値のセットに含まれていることを確認 validates_length_of # 文字列の長さが指定された長さであることを確認(最大値、最小値を設定可能) validates_numericality_of # 数値であることを確認(only_integer => trueとすると整数であることを確認) validates_presence_of # 空でないことを確認 validates_uniqueness_of # ユニークであることを確認
続きはまた。