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
其實不一定要做兩邊的宣告
假設你只在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
多對多關係: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 關聯行為的時候。這種時候透過傳入選項,以及建立關聯時,便可輕易完成
參考資料: