DataMapper でカスタムリレーション
DataMapper - Associations の「Customizing Associations」に書いてある。
User と Message というモデルがあり,Message には宛先が(複数)指定できる,とする。できるだけ規約ベースで書くと以下のようになる。
class User include DataMapper::Resource property :id, Serial has n, :message_receipients has n, :messages, :through => :message_receipients end class Message include DataMapper::Resource property :id, Serial has n, :message_receipients has n, :users, :through => :message_receipients end class MessageReceipient include DataMapper::Resource property :id, Serial belongs_to :user belongs_to :message end u = User.create m = Message.new m.users << u m.save p m.users p u.messages
でもこれだと,「宛先」ぽさとか User の「受信したメッセージ」ぽさの意図がなくなってわかりにくい。
class User has n, :message_receipients, :child_key => [ :receipient_id ] has n, :received_messages, :model => 'Message', :through => :message_receipients, :via => :message end class Message has n, :message_receipients has n, :receipients, :model => 'User', :through => :message_receipients end class MessageReceipient belongs_to :receipient, :model => 'User' belongs_to :message end u = User.create m = Message.new m.receipients << u m.save p m.receipients p u.received_messages
要するに :child_key
とか (今回は使ってないけど) :parent_key
とか :via
などのオプションを使えば,リレーション時にどのような外部キーを使うかなどをカスタマイズできる。
新規開発だけでなくレガシースキーマを相手にする場合にも。
まぁ ORM でリレーションまでやってしまうかどうかという問題もあるけど。