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一样


<<:  Transactions (3-2) - Weak Isolation Levels - Snapshot Isolation

>>:  Day 2 : Git 基本操作

Day18 NodeJS-Express III

Express的学习从安装、Route和Middleware的概念开始,今天要进入前端实务面的部份:...

[Day 5] 站在巨人的肩膀上 - 回顾股票市场交易论文

一、前言 矮子能看得更远,只因为他站在巨人的肩膀上。 - Isaac Newton 今天的文章,我将...

[鼠年全马] W33 - Vue出一个旅馆预约平台(7)

这周继续来做 [预约页面] 回顾一下上周切的区块 [标题] (已完成) [预约功能] [房间详细] ...

每日挑战,从Javascript面试题目了解一些你可能忽略的概念 - Day29

tags: ItIron2021 Javascript 前言 倒数第二天~昨天突然来一记Big(O)...

Day 4 Scanner取得使用者输入的数

如标题所示 scanner 是取得使用者输入的数,我们的程序不可能一直都是写死的,许多时候我们会需要...