今天我們要來講多對多
什麼是多對多
舉個例子:
接下來,奉上圖解!
那我們來開始做多對多拉
1.第三方Model僅需存放兩邊(商店和商品)Model的id,若想要額外增加一些欄位也是可行的
1.自動加上索引,加快查詢的速度
2.自動幫Model加上belongs_to
2.執行rails db:migrate
3.讓我們來編輯planet這個檔案
上面有說到,因為我們使用了references的寫法,所以Ruby on Rails 會自動幫我們補上這兩行
belongs_to :store
belongs_to :product
5.Product Model加上這兩行
關係圖解如下:
接下來,進入 rails c
看看
1.先取任意兩間商店 => store1和 store2
> store1 = Store.find(1)
Store Load (0.3ms) SELECT "stores".* FROM "stores" WHERE "stores"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<Store id: 1, title: "良心商店", tel: nil, address: nil, user_id: 1, created_at: "2021-10-10 09:...
> store2 = Store.find(2)
Store Load (0.3ms) SELECT "stores".* FROM "stores" WHERE "stores"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
=> #<Store id: 2, title: "三眼怪行星", tel: nil, address: nil, user_id: 2, created_at: "2021-10-10 0...
2.隨意取出2件商品 => product1和 product2
> product1 = Product.find(1)
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<Product id: 1, name: "吃吃喝喝商店", description: nil, price: 0.2e3, is_available: nil, store_i...
> product2 = Product.find(2)
Product Load (0.3ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
=> #<Product id: 2, name: "我想要飛", description: nil, price: 0.1e4, is_available: nil, store_id: 1...
3.把product1, product2丟給store2,把product1, product2丟給store1
> store2.products = [product1, product2]
Product Load (0.1ms) SELECT "products".* FROM "products" INNER JOIN "planets" ON "products"."id" = "planets"."product_id" WHERE "planets"."store_id" = ? [["store_id", 2]]
TRANSACTION (0.0ms) begin transaction
Planet Create (0.5ms) INSERT INTO "planets" ("store_id", "product_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["store_id", 2], ["product_id", 1], ["created_at", "2021-10-12 15:24:01.126751"], ["updated_at", "2021-10-12 15:24:01.126751"]]
Planet Create (0.1ms) INSERT INTO "planets" ("store_id", "product_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["store_id", 2], ["product_id", 2], ["created_at", "2021-10-12 15:24:01.128415"], ["updated_at", "2021-10-12 15:24:01.128415"]]
TRANSACTION (0.5ms) commit transaction
=> [#<Product id: 1, name: "吃吃喝喝商店", description: nil, price: 0.2e3, is_available: nil, store_...
> store1.products = [product1, product2]
Product Load (0.4ms) SELECT "products".* FROM "products" INNER JOIN "planets" ON "products"."id" = "planets"."product_id" WHERE "planets"."store_id" = ? [["store_id", 1]]
TRANSACTION (0.1ms) begin transaction
Planet Create (0.5ms) INSERT INTO "planets" ("store_id", "product_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["store_id", 1], ["product_id", 1], ["created_at", "2021-10-12 15:24:12.087711"], ["updated_at", "2021-10-12 15:24:12.087711"]]
Planet Create (0.1ms) INSERT INTO "planets" ("store_id", "product_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["store_id", 1], ["product_id", 2], ["created_at", "2021-10-12 15:24:12.089616"], ["updated_at", "2021-10-12 15:24:12.089616"]]
TRANSACTION (1.0ms) commit transaction
=> [#<Product id: 1, name: "吃吃喝喝商店", description: nil, price: 0.2e3, is_available: nil, store_...
> product1.stores.count
(0.5ms) SELECT COUNT(*) FROM "stores" INNER JOIN "planets" ON "stores"."id" = "planets"."store_id" WHERE "planets"."product_id" = ? [["product_id", 1]]
=> 2
> product2.stores.count
(0.5ms) SELECT COUNT(*) FROM "stores" INNER JOIN "planets" ON "stores"."id" = "planets"."store_id" WHERE "planets"."product_id" = ? [["product_id", 2]]
=> 2
因為在store1和store2都有販售product1與product2,因此為兩家,我們看一下上面的SQL語法,我們就可以得知,他不再對Store與Product要資料,而是與第三方planet進行查詢的動作!
與前面的差別在於,
今天分享到這,每天進步一點點
參考資料:為你自己學Ruby on Rails