iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Modern Web

一探紅寶石的神秘面紗 - Ruby 及 Rails入門介紹 系列系列 第 22

Day 22 - 進入Rails世界必須懂:Model 關聯性 (1:1)

  • 分享至 

  • xImage
  •  

想好好學會rails,不得不好好認識相當重要的關聯性,能夠理解並善用的話,你就能在各個model之間進行資料庫的溝通,拿到你想要的資料。

Model 關聯性

Rails的 Model 關聯主要有三種類型

  • 一對一 (1:1)
  • 一對多 (1:N)
  • 多對多 (N:N)

今天這部分章節,會優先介紹1對1。
我們用實際的例子來進行說明會更加清楚。

1:1 一對一

假如我們今天想要開一間飲料店
我們會有一個店長 Owner
一個店長會有一間店 Store

假設每個店長可以開一間店,這種關係就是一對一的關係。
=> Owner has one store

可以先從 rails 中產生 Owner 的 Model 並生成對應的資料表來記錄店長的資訊

rails g model Owner name phone:integer

再產生 Store 的 Model 並生成對應的資料表來記錄商店的資訊,由於需要多一個 owner_id 所以透過指令 owner:references 或是 owner:belongs_to 來產生,這一個欄位可以讓我們知道

rails g model Store name tel address owner:references
rails g model Store name tel address owner:belongs_to (同上一行)


兩者的關係可以看到上圖表示,在onwer的model裡面可以加上對應的關聯,如果需要讓兩者之間有所關聯,belongs to 的那方就要有對應的 id 去紀錄,這邊就是透過 owner_id 。

has one 建立及產生的方法

到 Owner model 建立 has_one 關聯

class Owner < ApplicationRecord
  has_one :store
end

關聯產生後就自動產生以下方法,你可以用來在controller 傳遞資料時進行關聯的查找,或是 console 中操作資料時使用。

store
store=
build_store
create_store

其中 build 和 create 差異,build 還沒存入資料庫,create 直接存入

用 console 建立一個 Owner 然後用 crate_store 建立一個 Store

Owner.create(name:"Sean", phone:"0912345678")
 
o1 = Owner.first

o1.create_store(name:"五石蘭", tel:"031234567", address:"新竹縣")

Store.last
 id: 1,                                                      
 name: "五石蘭",                                             
 tel: "031234567",                                           
 address: "新竹縣",                                          
 owner_id: 1,                                                
 created_at: Fri, 07 Oct 2022 07:22:23.353390000 UTC +00:00,
 updated_at: Fri, 07 Oct 2022 07:22:23.353390000 UTC +00:00> 
 

belongs_to 建立及產生的方法

在 store 的 model 裡面也看到已經加好的關聯 (owner:references/owner:belongs_to 自動產生),如果沒有透過之前指令也可以自己加上去,或是你沒有要用到產生的方法也可以不寫。

class Store < ApplicationRecord
  belongs_to :owner
end

加上後也會因關聯產生後就自動產生以下方法

owner
owner=

用上面建立好的 store 可以反向利用 owner 查到擁有者是誰,你也可以用 onwer= 來更改擁有者的資料

s1 = Store.last

s1.owner
  Owner Load (0.5ms)  SELECT "owners".* FROM "owners" WHERE "owners"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 =>                                                               
#<Owner:0x00007f8e292a7308                                        
 id: 1,                                                           
 name: "Sean",                                                    
 phone: "0912345678",                                             
 created_at: Fri, 07 Oct 2022 07:18:45.627220000 UTC +00:00,      
 updated_at: Fri, 07 Oct 2022 07:18:45.627220000 UTC +00:00>      

補充:

  1. has_one 跟 belongs_to 方法需要同時設定嗎?
    不一定。如果不需要「從 Store 反查 Owner」的方法,那 belongs_to 就不需要設定了。或是不需要從 Owner 創建 store 或是查詢,也可以不用寫 has_one。

  2. 如果只設定 has_one 或 belongs_to 其中一項的話會怎樣?
    有設定的話就會有方法,沒設定也沒關係,依造自己需要進行設定。


參考資料:

  1. 為你自己學 Ruby on Rails

上一篇
Day 21 - 進入Rails世界必須懂:Migration
下一篇
Day 23 - 進入Rails世界必須懂:Model 關聯性 (1:N)
系列文
一探紅寶石的神秘面紗 - Ruby 及 Rails入門介紹 系列30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言