活动记录关联的回调

时间:2011-06-23 20:24:08

标签: ruby-on-rails activerecord callback one-to-many

我有一个休假审批模式has_many:条目有一种方法,如果我销毁其中一个条目,其余的被销毁?我还想发送一封电子邮件,如果是,但不是每个条目都有一封。有没有办法观察整个集合的变化?

5 个答案:

答案 0 :(得分:1)

我认为这应该有效:

class Entry < ActiveRecord::Base
  belongs_to :vacation_request, :dependent => :destroy

  # ...
end

class VacationApproval < ActiveRecord::Base
  has_many :entries, :dependent => :destroy

  # ...
end

当一个Entry被销毁时,相关的VacationApproval将被销毁,随后所有相关的Entries将被销毁。

请告诉我这是否适合您。

答案 1 :(得分:1)

您可以使用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

在你将代码用于任何重要的代码之前,一定要对代码进行测试,但它应该为你提供一些入门指导。

答案 2 :(得分:1)

回调可能不是一个好选择,因为:

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

答案 3 :(得分:0)

所以我最终做的是

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响应时删除所有这些,这是不可取的。

由于我不关心它们仍然在那里,只要条目无法提交即可。

这对我来说是最简单/最安全/递归友好的方式,但可能不是最好的方法。感谢你的帮助!

答案 4 :(得分:0)

对任何好奇/寻求信息的人

我最后通过设置像这样的假期APProval模型

来解决这个问题
class VacationApproval < ActiveRecord::Base
    has_many :entries , :conditions => {:job_id => Job.VACATION.id }, :dependent => :delete_all
end

和My Entry Model就是这样

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不处理回调,只删除它们