iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
Modern Web

Ruby新手村的礦工日記系列 第 26

[ Day 26 ] Rails : Model 的關聯性(一對一)

  • 分享至 

  • xImage
  •  

在一個 Rails 專案中,你一定會有很多的 Model,這些 Model 之間也許會有一些關聯性,那為什麼 Model 之間要有關聯呢?這些關聯使我們程式碼寫起來更簡單,也簡化了常見的操作。

Model 關聯有哪些?

在 Rails 中 Model 主要分成三種關聯:

  • 一對一
  • 一對多
  • 多對多

接下來,用一個簡單的商店系統來說明這些關聯性:

  1. 一對一:每個擁有者 (Owner) 可以開一間店 (Store)。
  2. 一對多:每間店 (Store) 會有很多商品 (Product)。
  3. 多對多:每間店 (Store) 可以有很多商品之外,每種商品也可以在很多店家被販賣。

Model 也會提供一些關聯的方法,如 has_onehas_manybelongs_to ,我們將這些方法搭配 Rails 的資料表慣例設定主鍵(Primary Key)及外部鍵(Foreign Key),使這些資料表串在一起。

一對一

先從簡的的一對一關聯開始,每個擁有者 (Owner) 可以開一間店 (Store),行きましょう!
我們先簡單的做兩個 Model :
Owner 的 Model:

$ rails g model Owner name tel:integer

Store 的 Model,並讓它屬於 Owner :

# Store
$ rails g model Store title address owner:references
或
$ rails g model Store title address owner:belongs_to

不管是 referencesbelongs_to 這兩種效果都是一樣的。
rails db:migrate 後,進到 schema.rb 來看看:
schema
這邊 Owner 其實沒什麼特別的,要注意 Store 裡面的 owner_id ,這個欄位的型態是數字,主要的用途是用來對應到 Owner Model 的 id 欄位,又稱它叫外部鍵(Foreign Key)。

Model 設定關聯

接著我們到 Model 看看:
owner model
store model
你會發現 Store 裡面有 belongs_to :owner ,但 Owner 卻什麼東西都沒有。
所以我們在 Owner 加上 has_one :store

class User < ApplicationRecord
  has_one :store
end

這樣我們就將這兩個 Model 的關聯建立起來了:
has_one
此時會自動產生以下的方法:

  1. store
  2. store=
  3. build_store (不會直接存進資料庫!)
  4. create_store (直接存進資料庫)

這些方法你可以在 cotroller 使用,也可以在 rails console 裡面用。

rails console 裡:

我們進到 rails console ,首先用 new 方法建一個 owner 以及 一個 Store :

>> owner1 = Owner.new(name: "春春")
=> #<Owner id: nil, name: "春春", tel: nil, created_at: nil, updated_at: nil> 
>> store1 = Store.new(title: "超夯麵包店",address: "台北")
=> #<Store id: nil, title: "超夯麵包店", address: "台北", owner_id: nil, created_at: nil, updated_at: nil> 

把 store1 指定給 owner1:

>> owner1.store = store1

接著 save :

>> owner1.save

owner save
這兩筆資料會被存進各自的資料表內,而且 store1 的owner_id 欄位會設定成 owner1 的 id
當我們去查 store1 時,你也會發現 owner_id: 1 :
store1
這時候我們就可以透過 store1 去找到他的 owner 是誰了:
store1.owner

我要直接開店,不要用別人給的

除了剛剛上面分開建立 owner1store1 之外,我們也可以用 owner 的角度去建立 store ,所以這邊我們用 build_storecreate_store 去開店:

>> owner2 = Owner.create(name: "阿肥")
>> owner2.create_store(title:"貓貓集散地", address:"衡陽路")

這樣就建好一間店了:
owner2.create_store
至於 build_store ,因為他的作法跟 create_store 相似,只差了一個 save,這邊就不多做贅述了。

參考資料:

  1. 為你自己學 Ruby on Rails
  2. Rails Guides

上一篇
[ Day 25 ] Rails : 聽說 Migration 是個狠角色?!
下一篇
[ Day 27 ] Rails : Model 的關聯性(一對多)
系列文
Ruby新手村的礦工日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言