2010-04-22 38 views
0

我有一種複雜的情況下,我想知道這將如何在鋼軌工作:複雜的ActiveRecord協會。通過第四表

我想分類一些歌手的流派。歌手可以屬於多個類型,用戶可以標記指定給每個流派

例如:

singers <-- singers_genres --> genres <-- genres_tags --> tags 

SQL看起來是這樣的:

SELECT * FROM singers S 
    INNER JOIN singers_genres SG ON S.id=SG.singer_id 
    INNER JOIN genres G ON G.id = SG.genre_id 
    LEFT OUTER JOIN genre_tags GT ON G.id = GT.genre_id 
    INNER JOIN tags T ON GT.tag_id = T.id 

下面列舉一下我的班看像:

class Singer 
    has_and_belongs_to_many :genres, :include => :tag 

class Genre 
    has_and_belongs_to_many :singers 
    has_and_belongs_to_many :tags 

class Tag 
    has_and_belongs_to_many :genres 
+0

你想知道如何指定的關聯這一要求或者你想知道做如何使用這些關聯訪問某些數據? – 2010-04-22 00:43:42

+0

我對如何設置關聯感到困惑。 – Dex 2010-04-22 01:14:57

回答

1

讓我們創建項目...

rails itunes 
cd itunes 

創建基本模型:

script/generate model Singer name:string 
script/generate model Genre name:string 
script/generate model Tag name:string 

進行遷移:

rake db:migrate 

更新機型:

class Singer < ActiveRecord::Base 
    has_and_belongs_to_many :genres 
end 

class Genre < ActiveRecord::Base 
    has_and_belongs_to_many :singers 
    has_and_belongs_to_many :tags 
end 

class Tag < ActiveRecord::Base 
    has_and_belongs_to_many :genres 
end 

創建用於連接表兩個遷移:

script/generate migration CreateGenresSingersJoin 
script/generate migration CreateGenresTagsJoin 
rake db:migrate 

的genres_singers模型:

class CreateGenresSingersJoin < ActiveRecord::Migration 
    create_table 'genres_singers', :id => false do |t| 
    t.integer 'genre_id' 
    t.integer 'singer_id' 
    end 

    def self.down 
    drop_table'genres_singers' 
    end 
end 

的genres_tags模型:

class CreateGenresTagsJoin < ActiveRecord::Migration 
    create_table 'genres_tags', :id => false do |t| 
    t.integer 'genre_id' 
    t.integer 'tag_id' 
    end 

    def self.down 
    drop_table'genres_tags' 
    end 
end 

在seeds.db創建一些播種數據,或無論如何:

Singer.create(:name => 'Lady Ga Ga') 
Genre.create(:name => 'Pop') 
Genre.create(:name => 'Folk') 
Tag.create(:name => 'Top50') 

插入一些鏈接數據:

INSERT INTO genres_singers (genre_id, singer_id) VALUES (1, 1) 
INSERT INTO genres_singers (genre_id, singer_id) VALUES (2, 1) 
INSERT INTO genres_tags (genre_id, tag_id) VALUES (1, 1) 

那麼我們可以使用的關聯,如:

Singer.first.genres.first.tags.first 
=> #<Tag id: 1, name: "Top50"> 

Singer.find_by_name("Lady Ga Ga").genres.first.tags 
=> [#<Tag id: 1, name: "Top50">] 
0

Choosing Between has_many :through and has_and_belongs_to_many是一個很好的介紹協會。

也許你可以在這裏發佈你的模型,看看這些關聯是如何設計的。

+0

我讀過這個,它是一個很好的資源,我可以使用:include參數進行二階關聯。 Rails能夠執行關聯有多深? – Dex 2010-04-22 01:29:29