進入Rails世界必須懂:Model 關聯性 (N:N)
多對多 N:N
關於多對多繼續用飲料店的例子舉例說明,可以想像我們很多間飲料店品牌,有很多飲料品項是相同的或不同,就會有需要有一張第三方表單來記錄:
- 一間飲料店可以有很多種飲料
- store has many drinks
- 同一種飲料可以被很多間不同的飲料店販賣
- drink has many stores
我們可以透過這張表單來知道,哪間店有賣哪些飲料,哪些飲料有被哪些店家販售。
他們之間的關係可以透過下面這張圖片看到,虛線的 has many 表示他們並不是真的直接有一對多的關聯,而是需要透過第三方表格來建立多對多關聯。
我們可以建立第三方的表格 drink_invest 來記錄飲料和店家之間的關係rails g model drink_invest store:references drink:references
加上 reference
或是 belongs_to
都可以讓這個表格自動建立出對應的 store_id 及 drink_id 欄位,並且可以:
- 自動加上索引(index),加快查詢
- 自動幫 Model 加上 belongs_to
需要建立這樣的第三方表格來建立關聯,是屬於多對多的關聯
drink 和 store 之間沒有直接 has_many 的關聯, 但可以使用 has_many through 去透過 drink_invest 建立多對多的關聯。
接著可以把相關的 model 建立好關聯
store.rb
1 | class Store < ApplicationRecord |
drink.rb
1 | class Drink < ApplicationRecord |
進入 rails console 試試看
先建立好我們需要的資料,店家、飲料、還有店家販售的飲料有哪些。
1 | s1 = Store.create(name:"五石蘭", tel:"031234567", address:"新竹縣", owner_id:1) |
查詢相關的資訊之後會注意到 sql 語法的變化,開始透過第三方表格進行查詢。
1 | # 有販售 d1 綠茶有幾家 |
可以發現,這些查詢的 SQL 語法中,都已經不是直接跟 Store 或 Drink 要資料,而是向 drink_invest 進行查詢。例如第二項查詢在 s1 跟 s2 都有 d2 這個商品,所以是 2 家。
「多對多」關連,在使用上就跟一般的「一對多」很像,但實際上的資訊都是記錄在第三方資料表裡。
參考資料:
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Sean's Blog!
評論
GiscusDisqus