iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Software Development

SQL rookie 之天天魯一下系列 第 6

Day 6 - 為Model、Database 加上關聯(1)

  • 分享至 

  • xImage
  •  

哈囉,大家好!

那麼我們今天開始為Model 和Database 加上關聯吧!

不知魯魯們是不是跟被翻爛的書一樣,每次聽到關聯就像斷片,除卻為什麼要加這件事情不談,本篇就先來單就該怎麼加討論吧!

你可能聽過:

:只加上 has_one、has_many、belongs_to 等還沒做完關聯?

:在資料表要加上PK、FK?

:那加了PK、FK 就算加上關聯了嗎?

:那到底怎麼樣才叫加了關聯、加了關聯與否又會有什麼差別呢?

首先,我們先看到Rails Guide - Active Record Association 篇:

1 Why Associations?
In Rails, an association is a connection between two Active Record models. Why do we need associations between models? Because they make common operations simpler and easier in your code.

在討論simpler and eaiser 是怎麼做到的前,我們不妨先來畫關聯圖,以便解釋後面的情境吧!
魯魯專案的Model 關聯圖_ver1

(以上為利用drawio 畫的,是流程圖、ER 圖的繪製利器)

釐清了自己資料表的關聯性後,我們就來試試以上幾個情境吧!

情境1:如果沒加上has_many、belongs_to,以Podcast、Episode 為例:

# 尚未加上has_many、belongs_to

irb(main):001:0> Podcast.last.episodes
  Podcast Load (0.5ms)  SELECT "podcasts".* FROM "podcasts" ORDER BY "podcasts"."id" DESC LIMIT $1  [["LIMIT", 1]]
Traceback (most recent call last):
        1: from (irb):4
NoMethodError (undefined method `episodes' for #<Podcast:0x00007fba05cea718>)
# 加上Podcast has_many :episodes

irb(main):002:0> Podcast.last.episodes
  Podcast Load (0.3ms)  SELECT "podcasts".* FROM "podcasts" ORDER BY "podcasts"."id" DESC LIMIT $1  [["LIMIT", 1]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR:  column episodes.podcast_id does not exist)
LINE 1: SELECT "episodes".* FROM "episodes" WHERE "episodes"."podcas..."
# 同理,沒加上Episode belongs_to :podcast

irb(main):003:0> Episode.last.podcast
  Episode Load (0.2ms)  SELECT "episodes".* FROM "episodes" ORDER BY "episodes"."id" DESC LIMIT $1  [["LIMIT", 1]]
Traceback (most recent call last):
        1: from (irb):25
NoMethodError (undefined method `podcast' for #<Episode:0x00007fb9ff9f6080>)

看到這邊,大概能知道has_many 和belongs_to 能為Model 增加association 的若干方法,那讓我們偷偷來看看究竟增加了哪些方法 XD:

irb(main):004:0> Episode.instance_methods.count
329

# 加上belongs_to :podcast 後
irb(main):005:0> Episode.instance_methods.count
336

大家也有興奮的感覺了嗎?我們來驗證看看多了哪些方法:

# 未加上belongs_to :podcast 前
methods_before = []
methods_before << Episode.instance_methods

# 加上belongs_to :podcast 後
reload!

methods_after = []
methods_after << Episode.instance_methods

# 有沒有興奮的感覺!XD
irb(main):022:0> methods_after.flatten - methods_before.flatten
[
    [0] "autosave_associated_records_for_podcast",
    [1] "build_podcast",
    [2] "create_podcast",
    [3] "create_podcast!",
    [4] "podcast",
    [5] "podcast=",
    [6] "reload_podcast"
]

我們可看到加上belongs_to 的方法後,會給予其上面的方法;而若加上has_on、has_many,也會給予其相對應的關聯方法,至於方法是什麼呢,我們就之後再補充說明啦!

補充:
has_one 給的方法
has_many 給的方法
has_and_belongs_to_many 給的方法
belongs_to 給的方法
來偷偷對一下上面的跟Rails Guide 列的方法:

# When you declare a belongs_to association, the declaring class automatically gains 8 methods related to the association:
association # ✔️
association=(associate) # ✔️
build_association(attributes = {}) # ✔️
create_association(attributes = {}) # ✔️
create_association!(attributes = {}) # ✔️
reload_association # ✔️
association_changed?
association_previously_changed?

# 所以就知道可以研究什麼了嗎?XD

...

那麼今天的文章就到這到一段落啦,謝謝大家~


上一篇
Day 5 - 插話:魯魯上色幫手——amazing print
下一篇
Day 7 - 為Model、Database 加上關聯(2)
系列文
SQL rookie 之天天魯一下30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言