我有三个activerecord类:Klass,Reservation和Certificate Klass可以有很多预订,每个预订可以有一个证书
定义如下......
class Klass < ActiveRecord::Base
has_many :reservations, dependent: :destroy, :autosave => true
has_many :certificates, through: :reservations
attr_accessible :name
def kill_certs
begin
p "In Kill_certs"
self.certificates.destroy_all
p "After Destroy"
rescue Exception => e
p "In RESCUE!"
p e.message
end
end
end
class Reservation < ActiveRecord::Base
belongs_to :klass
has_one :certificate, dependent: :destroy, autosave: true
attr_accessible :klass_id, :name
end
class Certificate < ActiveRecord::Base
belongs_to :reservation
attr_accessible :name
end
我希望能够通过调用Klass#kill_certs(上图)来删除/销毁klass控制器中特定klass的所有证书
但是,我收到一条消息的例外:
"In RESCUE!"
"Cannot modify association 'Klass#certificates' because the source
reflection class 'Certificate' is associated to 'Reservation' via :has_one."
我(还尝试将预订类更改为“has_many:certificates”,然后错误是...
"In RESCUE!"
"Cannot modify association 'Klass#certificates' because the source reflection
class 'Certificate' is associated to 'Reservation' via :has_many."
奇怪的是,我可以从控制台执行Klass.first.certificates,并检索第一个类中的证书,但是我不能在没有创建错误的情况下执行Klass.first.certificates.delete_all。我错过了什么吗?
这是唯一的方法..
Klass.first.reservations.each do |res|
res.certificate.destroy
end
感谢您的帮助。
答案 0 :(得分:4)
RoR docs对此有明确的解释(仅对TLDR读取粗体):
从关联中删除
什么被删除?
这里有一个潜在的陷阱:has_and_belongs_to_many和 has_many:通过关联在连接表中有记录,以及 相关记录。所以当我们调用其中一种删除方法时, 究竟应该删除什么?
答案是假设关联上的删除是 关于删除所有者和相关联之间的链接 对象,而不一定是关联对象本身。 所以使用has_and_belongs_to_many和has_many:through,加入 记录将被删除,但相关记录将不会被删除。
如果您考虑一下,这是有道理的:如果您打电话 post.tags.delete(Tag.find_by(姓名:&#39;食物&#39;))你会想要'食物' 标签要从帖子中取消链接,而不是标签本身 从数据库中删除。
然而,有些例子表明这种策略没有意义。 例如,假设一个人有很多项目,每个项目都有 很多任务。如果我们删除了一个人的任务,我们可能会 不希望删除项目。在这种情况下,删除 方法实际上不会起作用:它只能在关联时使用 连接模型是belongs_to。在其他情况下,您是期望的 直接在相关记录或 :通过协会。
对于常规的has_many,没有区别 “关联记录”和“链接”,因此只有一个选择 什么被删除。
使用has_and_belongs_to_many和has_many:通过,如果你想 删除相关记录本身,你可以随时做一些事情 沿着person.tasks.each(&amp;:destroy)的路线。
所以你可以这样做:
self.certificates.each(&:destroy)