【发布时间】:2011-06-23 20:24:08
【问题描述】:
我有一个 has_many :entries 的假期批准模型,如果我销毁其中一个条目以销毁其余条目,有没有办法?如果是,我也想发送一封电子邮件,但不是每个条目都发送一封。有没有办法观察整个集合的变化?
【问题讨论】:
标签: ruby-on-rails activerecord callback one-to-many
我有一个 has_many :entries 的假期批准模型,如果我销毁其中一个条目以销毁其余条目,有没有办法?如果是,我也想发送一封电子邮件,但不是每个条目都发送一封。有没有办法观察整个集合的变化?
【问题讨论】:
标签: ruby-on-rails activerecord callback one-to-many
回调可能不是一个好的选择,因为:
class Entry < ActiveRecord::Base
def after_destroy
Entry.where(:vacation_id => self.vacation_id).each {|entry| entry.destroy}
end
end
会产生一些不好的递归。
这可能是你应该在控制器中进行:
class EntriesController < ApplicationController
def destroy
@entry = Entry.find(params[:id])
@entries = Entry.where(:vacation_id => @entry.vacation_id).each {|entry| entry.destroy}
#send email here
...
end
end
【讨论】:
您可以使用before_destroy 回调。
class VacationRequest < ActiveRecord::Base
has_many :entries
end
class Entry < ActiveRecord::Base
belongs_to :vacation_request
before_destroy :destroy_others
def destroy_others
self.vacation_request.entries.each do |e|
e.mark_for_destruction unless e.marked_for_destruction?
end
end
end
在将代码用于任何重要的事情之前,一定要对其进行测试,但它应该为您提供一些开始的方向。
【讨论】:
mark_for_destruction 只对 :autosave 有用,所以当我看到 :dependent => destroy 会发生什么时,我试试看
:autosave。不过要小心你把:dependent => :destroy放在哪里。您是否希望 VacationRequest 本身在其任何条目被销毁时也被销毁?
我认为这应该可行:
class Entry < ActiveRecord::Base
belongs_to :vacation_request, :dependent => :destroy
# ...
end
class VacationApproval < ActiveRecord::Base
has_many :entries, :dependent => :destroy
# ...
end
应该发生的是,当一个条目被销毁时,关联的 VacationApproval 将被销毁,随后其所有关联的条目将被销毁。
让我知道这是否适合你。
【讨论】:
所以我最终做的是
class VacationApproval < ActiveRecord::Base
has_many :entries , :conditions => {:job_id => Job.VACATION.id }, :dependent => :nullify
class Entry < ActiveRecord::Base
validates_presence_of :vacation_approval_id ,:if => lambda {|entry| entry.job_id == Job.VACATION.id} , :message => "This Vacation Has Been Canceled. Please Delete These Entries."
然后
@entries.each {|entry| entry.destroy if entry.invalid? }
在我的控制器的索引操作中。 和
`raise "Entries are not valid, please check them and try again ( Did you cancel your vacation? )" if @entries.any? &:invalid?`
在提交操作中
同时删除其他人的问题是,如果我的 UI 进行 10 次 Ajax 调用以选择 10 行,并且在我第一次以 9 个未处理的 404 响应结束时将其全部删除,这是不可取的。
既然我不在乎,它们就留在那儿,只要不能提交条目就可以了。
这对我来说是最简单/最安全/递归友好的方式,但可能不是最好的方式。感谢你的帮助!
【讨论】:
致任何好奇/寻求信息的人
我后来通过这样设置 The Vacation APProval 模型解决了这个问题
class VacationApproval < ActiveRecord::Base
has_many :entries , :conditions => {:job_id => Job.VACATION.id }, :dependent => :delete_all
end
和我这样的入口模型
class Entry < ActiveRecord::Base
after_destroy :cancel_vacation_on_destory
def cancel_vacation_on_destory
if !self.vacation_approval.nil?
self.vacation_approval.destroy
end
end
end
使用 :delete_all 不会处理回调,它只是删除它们
【讨论】: