活动记录关联的回调

发布于 2024-11-16 22:16:11 字数 107 浏览 0 评论 0原文

我有一个 has_many :entries 的假期审批模型,如果我销毁其中一个条目,是否可以销毁其余条目?如果是的话,我也想发送一封电子邮件,但不是每个条目都发送一封。有没有办法观察整个集合的变化?

I have a vacation approval model that has_many :entries is there a way that if I destroy one of those entries to have the rest destroyed? I also want to send one email if they are, but not one for each entry. Is there a way to observe changes to the collection as a whole?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ゃ懵逼小萝莉 2024-11-23 22:16:11

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

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

A callback probably isn't a good choice because:

class Entry < ActiveRecord::Base
  def after_destroy
    Entry.where(:vacation_id => self.vacation_id).each {|entry| entry.destroy}
  end
end

would produce some bad recursion.

It could be that you should do it in the controller:

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
窗影残 2024-11-23 22:16:11

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

在将代码用于任何重要的事情之前,一定要测试该代码,但它应该为您提供一些入门方向。

You can use the before_destroy callback.

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

Definitely test that code before you use it on anything important, but it should give you some direction to get started.

南…巷孤猫 2024-11-23 22:16:11

我认为这应该可行:

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

  # ...
end

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

  # ...
end

应该发生的是,当一个条目被销毁时,关联的 VacationApproval 将被销毁,随后其所有关联的条目将被销毁。

让我知道这是否适合您。

I think this ought to work:

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

  # ...
end

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

  # ...
end

What should happen is that when an Entry is destroyed, the associated VacationApproval will be destroyed, and subsequently all of its associated Entries will be destroyed.

Let me know if this works for you.

想念有你 2024-11-23 22:16:11

所以我最终做的是

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

因为我不在乎它们会留在那里,只要参赛作品不能提交就可以了。

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

So What i ended up doing is

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."

and then

@entries.each {|entry| entry.destroy if entry.invalid? }

in the index action of my controller.
and

`raise "Entries are not valid, please check them and try again ( Did you cancel your vacation? )" if @entries.any? &:invalid?` 

in the submit action

The problem with deleting the others at the same time is if my UI makes 10 Ajax calls to selete 10 rows, and it deletes all of them the first time I end up with 9 unahandled 404 responses, which was undesirable.

Since I don't care it they remain there, as long as the Entry cannot be submitted its OK.

This was the easiest / safest / recursion friendly way for me, but is probably not the best way. Thanks for all your help!

蓝梦月影 2024-11-23 22:16:11

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

我最终通过设置像这样的假期批准模型

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

To anyone curious/ seeking info

I ended up solving this later by setting The Vacation APProval model like this

class VacationApproval < ActiveRecord::Base
    has_many :entries , :conditions => {:job_id => Job.VACATION.id }, :dependent => :delete_all
end

and My Entry Model like this

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

Using :delete_all does not process callbacks, it just deletes them

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文