iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0

什麼是關聯性?

在 Ruby on Rails 中,關聯性是一種用於建立 Model 之間關聯的技術, Model 是應用程式中用於儲存和操作數據的結構,在 Rails 裡所謂的關係,是指在 Model 層級的關係,主要是透過 Model 的方法(例如 has_many 或 belongs_to)搭配 Rails 的資料表慣例設定主鍵(Primary Key)及外部鍵(Foreign Key),讓這些資料表串在一起

Rails 支援的關連

  • has_one
  • has_many
  • belongs_to
  • has_one :through
  • has_many :through
  • has_and_belongs_to_many(HABTM)

定義關聯性

has_one 關聯

has_one 關聯通常用於建立一對一的關聯。例如,假設我們有一個用戶(User)模型和一個個人資料(Profile)模型,每個用戶只有一個個人資料:

class User < ApplicationRecord
  has_one :profile
end

has_many 關聯

has_many 關聯用於建立一對多的關聯。例如,假設我們有一個作者(Author)模型和一個文章(Article)模型,每個作者可以寫多篇文章:

class Author < ApplicationRecord
  has_many :articles
end

belongs_to 關聯

belongs_to 關聯用於建立一對一或多對一的關聯。例如,假設我們有一個文章(Article)模型和一個作者(Author)模型,每篇文章都屬於一個作者:

class Article < ApplicationRecord
  belongs_to :author
end

has_one :through 關聯

當使用 has_one :through 關聯時,通常會有三個模型之間的關聯,其中一個模型(中介模型)用於建立連接另外兩個模型的關聯

這邊以 Patient(病人)、Doctor(醫生)和 Appointment(預約)來做例子:

# Patient(病人)
class Patient < ApplicationRecord
  has_one :medical_record
  has_one :doctor, through: :medical_record
end

# Doctor(醫生)
class Doctor < ApplicationRecord
  has_many :appointments
  has_many :patients, through: :appointments
end

# Appointment(預約)
class Appointment < ApplicationRecord
  belongs_to :doctor
  belongs_to :patient
end

has_many :through 關聯

has_many :through 關聯用於建立通過一個中介模型的多對多關聯。例如,假設我們有一個學生(Student)模型、一個課程(Course)模型和一個成績(Grade)模型,一個學生可以參加多門課程,一門課程也可以有多名學生,同時還可以記錄每個學生在每門課程的成績:

class Student < ApplicationRecord
  has_many :grades
  has_many :courses, through: :grades
end

has_and_belongs_to_many 關聯

has_and_belongs_to_many 關聯用於建立多對多的關聯。例如剛剛的例子,一樣假設我們有一個學生(Student)模型和一個課程(Course)模型,一個學生可以參加多門課程,一門課程也可以有多名學生:

class Student < ApplicationRecord
  has_and_belongs_to_many :courses
end

class Course < ApplicationRecord
  has_and_belongs_to_many :students
end

預告

明天預計來介紹 N + 1,我們明天見!


上一篇
Day 22 - Validation 資料驗證
下一篇
Day 24 - Rails N + 1 問題
系列文
Zero to Ruby on Rails30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言