iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 23
1

model關聯關係有以下幾種:

belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many

一對一關係:belongs_to/has_one

belongs_to 關聯宣告一個 Model 實體,屬於另一個 Model 實體。has_one 關聯建立兩個 Model 之間的一對一關係,但語義和結果與 belongs_to 不同。has_one 關聯宣告一個 Model 實體,含有(或持有)另一個 Model 實體。
一對一的關係其實很好理解,舉例來說: 每一個使者者(User)只有一個登入帳號(Account)
先建立model:

$ rails g model User name email
$ rails g model Account account_number user_id:integer
$ rails db:migrate

這邊要注意的是,我們在Account這個Model建立一個user_id:integer,他主要是用來跟User這個Tabel的User.id做連結(這個概念其實叫做外部鍵foreign key),在Rails的慣例中,他會是對應到的Model名稱_id。
剛剛建立的只是兩個Model的架構,現在要幫兩個Model建立關聯:

class User < ActiveRecord::Base
  has_one :account
end
class Account < ActiveRecord::Base
  belongs_to :user
end

你可以直接從字面上的意思去解讀:
User這個類別只對應到一個(has_one) Account,
每一個Account都是屬於(belongs_to) User的。

belongs_to/ has_one 關聯方法

設定關聯後,Model 可以使用這些實體方法:

.user
.user=
.build_user
.create_user

而User 這個Model 可以使用這些實體方法:

.account
.account=
.build_account
.create_account

我們來進 console 試玩看看:
先建立user 跟 account

https://ithelp.ithome.com.tw/upload/images/20191007/20118842ux2FVrHSHC.png

https://ithelp.ithome.com.tw/upload/images/20191007/20118842000jCvNJEa.png

其實不一定要做兩邊的宣告
假設你只在Account宣告belongs_to User,而沒有在User宣告has_one;那就只有Account擁有這些方法,能夠用act1.user讀取到User,User則無法讀取Acccount,反之亦然;但如果你沒有從User讀取Acccount的需求,不寫他的has_one也無妨,宣告只是方便互相做讀寫。

設定 account belong_to user

class Account < ActiveRecord::Base
  belongs_to :user
end

user 不做設定

class User < ActiveRecord::Base
end
act1.user		   #讀取成功
user1.account			#錯誤
註:在Rails5後,在沒有User的情況下create一個Acount,其實是寫不進去的。
這是 Rails 5 之後對 belongs_to 加入的新限制,需要有User才能建立Account。

一對多關係:belongs_to/has_may

has_many 關聯建立兩個 Model 之間的一對多關係。通常 has_many 另一邊對應的是 belongs_to 關聯。has_many 關聯宣告一個 Model 實體,有零個或多個Model 實體。
舉例來說:每個 User 有多個 friend
先建立Friend的Model,user_id同樣用來跟User做連結

$ rails generate model Friend name:string user_id:integer
$ rails db:migrate
#user.rb
class User < ApplicationRecord
  has_one :account
  has_many :friends
end
class Friend < ApplicationRecord
  belings_to :user
end

建立 user 有三個 friend

user1.friends << Friend.new(name:'friend1')
user1.friends << Friend.new(name:'friend2')
user1.friends << Friend.new(name:'friend3')

查詢user1的所有朋友

User.friend.all

https://ithelp.ithome.com.tw/upload/images/20191007/20118842u2rCXEy82o.png

多對多關係:has_many :through 關聯

has_many :through 關聯通常用來建立兩個 Model 之間的多對多關係。has_many :through關聯透過(through)第三個 Model,宣告一個 Model 實體,可有零個或多個另一個 Model 實體。

舉個醫療的例子,病患 需要透過 預約來見“中醫師”。相對應的宣告如下:

class Physician < ActiveRecord::Base
  has_many :appointments
  has_many :patients, through: :appointments
end
 
class Appointment < ActiveRecord::Base
  belongs_to :physician
  belongs_to :patient
end
 
class Patient < ActiveRecord::Base
  has_many :appointments
  has_many :physicians, through: :appointments
end

belongs_to 關聯支援選項:

Rails 的預設設定足夠應付多數狀況,但總會有需要客製化 belongs_to 關聯行為的時候。這種時候透過傳入選項,以及建立關聯時,便可輕易完成

https://ithelp.ithome.com.tw/upload/images/20191007/201188421o5YZHnvqQ.png

參考資料:

為你自己學ruby on rails


上一篇
DAY 22 model 驗證
下一篇
DAY 24 資料庫(SQL) ORM
系列文
毫無基礎學習 Ruby on Rails 的 甘苦心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言