обратные вызовы для активных ассоциаций записи - PullRequest
1 голос
/ 24 июня 2011

У меня есть модель утверждения отпуска, которая has_many: записи Есть ли способ, если я уничтожу одну из этих записей, чтобы уничтожить остальные? Я также хочу отправить одно электронное письмо, если оно есть, но не одно для каждой записи. Есть ли способ наблюдать изменения в коллекции в целом?

Ответы [ 5 ]

1 голос
/ 24 июня 2011

Вы можете использовать обратный вызов 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

Определенно протестируйте этот код, прежде чем использовать его на чем-то важном, но он должен дать вам некоторое руководство для начала.

1 голос
/ 24 июня 2011

Обратный вызов, вероятно, не является хорошим выбором, потому что:

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
1 голос
/ 24 июня 2011

Я думаю, что это должно сработать:

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

  # ...
end

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

  # ...
end

Что должно произойти, так это то, что когда запись уничтожена, ассоциированное одобрение VacationApproval будет уничтожено, и впоследствии все связанные с ним записи будут уничтожены.

Дайте мне знать, если это работает для вас.

0 голосов
/ 14 июля 2011

Любой, кто интересуется / ищет информацию

Я решил эту проблему позже, установив модель 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 не обрабатывает обратные вызовы, он просто удаляет их

0 голосов
/ 24 июня 2011

Итак, что я в итоге сделал, это

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? }

в действии index моего контроллера. и

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

в действии отправки

Проблема с одновременным удалением остальных заключается в том, что мой пользовательский интерфейс делает 10 Ajax-вызовов, чтобы выбрать 10 строк, и удаляет их все в первый раз, когда я получаю 9 необработанных 404 ответов, что было нежелательно.

Так как мне все равно, они остаются там до тех пор, пока Заявка не может быть подана, все в порядке.

Это был самый простой / безопасный / рекурсивный способ для меня, но, вероятно, не самый лучший. Спасибо за вашу помощь!

...