Ruby on Rails/ActiveRecord/Associations
關聯是連線兩個模型的方法。物件操作變得非常簡單。關聯描述了模型之間關係的作用。ActiveRecord 關聯可以用來描述模型之間的一對一 (1:1)、一對多 (1:n) 和多對多 (n:m) 關係。有幾種型別的關聯
- belongs_to 和
- has_one 形成一對一關係
- has_one :through 是一種建立一對一關係的不同方法
- has_many 和
- belongs_to 形成一對多關係
- has_and_belongs_to_many 或另一種方法
- has_many :through 建立多對多關係
對於所有以下示例,我們假設以下 4 個模型
class Product < ActiveRecord::Base
end
class Category < ActiveRecord::Base
end
class Rating < ActiveRecord::Base
end
class Tag < ActiveRecord::Base
end
也檢視以下模型的 ER 圖
該belongs_to關聯建立與其他模型的一對一 (1:1) 或一對多 (1:n) 關係。
在我們的示例中,一個 Rating 屬於一個 Product,因此我們需要設定一個belongs_to關聯。
class Product < ActiveRecord::Base
belongs_to :rating
end
產品儲存 Rating 的 ID,它們之間有一對一關係。這意味著:一個產品屬於一個類別,一個產品屬於一個 Rating。
該has_one關聯也是一對一關係。它宣告 Product 模型中的每個產品例項都只有一個 rating_id。
class Rating< ActiveRecord::Base
has_one :product
end
由於 Rating 和 Product 之間存在一對一關係,因此我們可以選擇將引用放在哪裡。因為我們將引用 (rating_id) 放入 Product (檢視 Product 模型中的 belongs_to :rating),因此 Rating 的關聯必須是 has_one:product。Has_one和belongs_to始終一起形成關係。
這是與其他模型的一對多連線。在這種情況下,一個類別有多個產品。注意拼寫,如果您使用has_many。您要引用的模型需要用複數形式。
class Category< ActiveRecord::Base
has_many :products #note the plural here!
end
class Product< ActiveRecord::Base
belongs_to :category
end
類別和產品形成一對多關係。由於一個類別有多個產品,因此我們將has_many關聯放在類別中。注意產品還需要包含對類別的引用。一個產品只屬於一個類別,因此我們將belongs_to :category放在 Product 模型中。
也稱為:HABTM。
Has_and_belongs_to_many是最複雜的關聯。您需要牢記一些事項:由於關係型資料庫的工作方式,您無法設定直接關係。您需要建立連線表。這可以透過遷移輕鬆完成。如果我們想為產品和標籤建立 HABTM 關聯,則連線表的關聯可能如下所示
class CreateProductTagJoinTable < ActiveRecord::Migration
def self.up
create_table :products_tags, :id => false do |t| #we DO NOT need the id here!
t.integer :product_id #alternatively, we can write t.references :product
t.integer :tag_id
end
end
def self.down
drop_table :products_tags
end
end
因為我們不需要在連線表中使用主鍵,所以我們使用:id => false來阻止自動建立主鍵列。表名必須按字母順序排列。字母 "P" 在 "T" 之前,因此表名必須是 products_tags(注意:複數)。
class Product< ActiveRecord::Base
has_and_belongs_to_many :tags
end
class Tag< ActiveRecord::Base
has_and_belongs_to_many :products
end
此關聯是形成多對多關係的另一種方法。請考慮以下 ER 圖來顯示關係。
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :supplier
end
class Supplier < ActiveRecord::Base
has_many :products
has_many :categories, :through => :products
end
class Category< ActiveRecord::Base
has_many :products
has_many :suppliers, :through => :products
end
我們不使用連線表,而是使用另一個模型來建立關係。如果我們想找出哪個供應商負責某個特定類別,我們需要使用產品將模型連線在一起。這樣,我們就可以在充當連線模型的真實模型中儲存更多資料。每當您需要儲存也屬於關聯的額外資料(例如建立日期)時,您可能希望使用這種型別的關聯。
與has_many :through, has_one :through關聯使用一個“額外”模型來形成關係。
請考慮這種視覺關係
class Network < ActiveRecord::Base
has_one :group
has_one :user, :through =>:group
end
class Group < ActiveRecord::Base
belongs_to :network
has_one :user
end
class User< ActiveRecord::Base
belongs_to :group
end
注意:此示例假設組內的成員資格對每個使用者都是排他的。


