Ruby on rails dependent::destroy-我可以用延迟的作业延迟此操作吗?
我有两个模型,一个存储事件,另一个是日历模型的连接模型。联接模型与远程日历API集成,并在创建或删除时通过API调用(通过保存前和销毁前回调)管理自身 当一次删除一条连接模型记录时,这种方法非常有效,但由于我在事件模型中定义了多个关联(我不希望远程日历中出现孤立事件),因此删除单个事件将导致N个api调用(其中N是连接模型记录的数量,可以假设为数千),这很容易导致超时 理想情况下,我希望延迟CalendarEvent.destroy调用,但仅在删除事件时调用。例如: Event.destroy[对所有CalendarEvent(加入模型)记录调用delay.destroy] CalendarEvent.destroy[在不延迟作业的情况下销毁] 有没有办法通过多次电话来推迟 有没有一种方法可以通过dependent:传递自定义销毁方法 在CalendarEvent.destroy方法中,是否有方法知道是否从依赖::destroy定义调用它 有没有办法通过多次电话来推迟 没有Ruby on rails dependent::destroy-我可以用延迟的作业延迟此操作吗?,ruby-on-rails,ruby,ruby-on-rails-4,activerecord,delayed-job,Ruby On Rails,Ruby,Ruby On Rails 4,Activerecord,Delayed Job,我有两个模型,一个存储事件,另一个是日历模型的连接模型。联接模型与远程日历API集成,并在创建或删除时通过API调用(通过保存前和销毁前回调)管理自身 当一次删除一条连接模型记录时,这种方法非常有效,但由于我在事件模型中定义了多个关联(我不希望远程日历中出现孤立事件),因此删除单个事件将导致N个api调用(其中N是连接模型记录的数量,可以假设为数千),这很容易导致超时 理想情况下,我希望延迟CalendarEvent.destroy调用,但仅在删除事件时调用。例如: Event.destroy[
有没有一种方法可以通过dependent:传递自定义销毁方法 也没有;在以下方面只有少数几个可接受的选项: :destroy导致所有关联对象也被销毁 :delete_all导致直接从数据库中删除所有关联对象(因此不会执行回调) :NULL导致外键设置为NULL。不执行回调 :restrict_with_exception导致在存在任何关联记录时引发异常 :restrict_with_error如果存在任何关联对象,则会将错误添加到所有者
在CalendarEvent.destroy方法中,是否有方法知道是否从依赖::destroy定义调用它 从技术上讲,您可以在
调用者中嗅探堆栈跟踪,但这听起来不是一个好主意
我将删除dependent:
选项,并在销毁后构建一个自定义,以延迟方式清理CalendarEvent
对象
after_destroy :destroy_calendar_events
def destroy_calendar_events
calendar_events.each {|event| event.delay.destroy }
end
很久以前,我工作过的一家公司解决了这个问题,它提供了一个异步销毁
方法,但这是基于并且需要修改的。如果你想加入一些东西,代码可能会很有趣。Kristján的答案可能会起作用,但我有外键问题。外键我们不想工作
然后,如果我试图延迟API服务对象本身,我的延迟作业想要将延迟作业的RSA密钥存储在DB条目中。Yikes。它无论如何都没有验证(空)密钥,因此在两个方面失败
然后我尝试在对象实例上延迟生成新API对象的方法。当然它失败了,因为延迟的作业试图加载对象(已经销毁)以运行作业。拍额头,尖叫,拉毛,重复
最终起作用的是调用一个类方法(或者它实际上可能是一个外部服务对象,等等),只传递字符串(不指望任何可以删除以提供必要信息的对象)
…然后DelayedJob才能成功运行任务
它没有我想要的那么棒,因为如果作业失败,远程事件可能会成为孤立事件,但对于我的用例来说,它已经足够好了。我只需要通过sidekiq或类似的方式在删除时启动作业。Close-可能在数据库中没有外键的情况下工作(没有依赖项的外键::destroy不想工作)。对我的特殊情况不起作用,但我会对这个答案进行投票,因为它可能对其他没有FK问题的人起作用。啊,外键约束是有意义的。老实说,尽管DBA神肯定会放弃我的来世,但我在一年前就停止使用外键约束,转而使用代码和测试,并且没有回头看。
class CalendarEvent
# bunch o' stuff
def destroy
self.class.delay.remove_remote_event!(user, remote_calendar_id, remote_id)
super
end
def self.remove_remote_event!(user, remote_calendar_id, remote_id)
EpGoogle::Interfaces::Calendar.new(user.email).delete_event(remote_calendar_id, remote_id)
end
end