iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
自我挑戰組

Ruby on Rails JS系列 第 4

Rails has_many

has_many 的設定

class_name
可以變更關聯的類別名稱,例如以下新增了paid_attendees關聯,和另一個has_many :attendees都關聯到同一個attendees table:

class Event < ApplicationRecord
	has_many :attendees
	has_many :paid_attendees, :class_name => "Attendee"
	#...
end
## foreign_key
可以變更Foreign Key的欄位名稱,例如改成paid_user_id:

class Event < ApplicationRecord
    belongs_to :paid_user, :class_name => "User", :foreign_key => "paid_user_id"
    #...
end
## scope

在第二個參數傳入匿名函式,可以設定關聯的範圍條件,例如:

class Event < ApplicationRecord
	has_many :attendees
	has_many :paid_attendees, -> { where(:status => "paid") }, :class_name => 'Attendee'
	#...
end
這個語法跟我們之前學過的Arel串接寫法是一樣的,所以可以繼續串接加上排序等其他條件:

class Event < ApplicationRecord
	has_many :attendees
	has_many :paid_attendees, -> { where(:status => "paid").order("id DESC") }, :class_name => 'Attendee'
	#...
end

dependent

可以設定當物件刪除時,怎麼處理依賴它的資料,例如:

class Event < ApplicationRecord
  has_many :attendees, :dependent => :destroy
end
其中:dependent可以設定有幾種不同的處理方式,例如:

:destroy 把依賴的attendees也一併刪除,並且執行Attendee的destroy回呼
:delete 把依賴的attendees也一併刪除,但不執行Attendee的destroy回呼
:nullify 不會幫忙刪除attendees,但會把attendees的外部鍵event_id都設成NULL
:restrict_with_exception 如果有任何依賴的attendees資料,則連event都不允許刪除。執行刪除時會丟出錯誤例外ActiveRecord::DeleteRestrictionError。
:restrict_with_error 不允許刪除。執行刪除時會回傳false,在@event.errors中會留有錯誤訊息。
如果沒有設定:dependent的話,就不會特別去處理。

要不要執行attendee的刪除回呼差在執行效率,如果需要回呼的話,必須一筆筆把attendee讀取出來變成attendee物件,然後呼叫它的destroy。如果用:delete的話,只需要一個SQL語句就可以刪除全部attendee了。

through

透過關聯來建立另一個關聯集合,用於建立多對多的關係。

class Event < ApplicationRecord
	has_many :event_groupships
   has_many :groups, :through => :event_groupships
end
source
搭配through設定使用,當關聯的名稱不一致的時候,需要加上source指名是哪一種物件。

class Event < ApplicationRecord
	has_many :event_groupships
   has_many :classifications, :through => :event_groupships, :source => :group
end

has_one 的集合物件

多了兩個方法可以新增關聯物件:

build_{association_name}
create_{association_name}
例如:

e = Event.first
e.build_location

has_one 的設定

class_name、dependent、scope條件等設定,都和has_many一樣


上一篇
Ruby on Rails Find Find_by Where 差別
下一篇
Rails belong_to
系列文
Ruby on Rails JS29

尚未有邦友留言

立即登入留言