Many-to-Many Relationships with Extra Data 带有数据的多对多关系
一般多对多关系都带有 一个存储关系的表 这表一般用处比较单一 但是有时也需要在这个表中添加除关系以外的数据 下面有个订杂志的例子
一般情况下
def self.up
create_table :magazines do |t|
t.column :title, :string
end
create_table :readers do |t|
t.column :name, :string
end
create_table :magazines_readers, :id => false do |t|
t.column :magazine_id, :integer
t.column :reader_id, :integer
end
但是 这个:magazines_readers 表 在添加一些属性后就可以作为一个订阅模型使用
不再是单纯存储:magazines 和:readers 的关系 如下
def self.up
drop_table :magazines_readers
create_table :subscriptions do |t|
t.column :reader_id, :integer
t.column :magazine_id, :integer
t.column :last_renewal_on, :date
t.column :length_in_issues, :integer
end
end
三个模型的设置如下
class Subscription < ActiveRecord::Base
belongs_to :reader
belongs_to :magazine
end
class Reader < ActiveRecord::Base
has_many :subscriptions
has_many :magazines, :through => :subscriptions
end
class Magazine < ActiveRecord::Base
has_many :subscriptions
has_many :readers, :through => :subscriptions
end
定义自己的查询方法
class Magazine < ActiveRecord::Base
has_many :subscriptions
has_many :readers, :through => :subscriptions
has_many :semiannual_subscribers,
:through => :subscriptions,
#注意这里用source
:source => :reader,
:conditions => ['length_in_issues = 6' ]
end
例子
chad> ruby script/console
>> Magazine.find(1).semiannual_subscribers
=> [#<Reader:0x26ba05c @attributes={"name"=>"Anthony Braxton", "id"=>"1"}>]