确定在Rails after_save回调中从数组中删除了哪些id?

时间:2011-10-02 09:10:28

标签: ruby-on-rails ruby-on-rails-3 callback after-save

我试图弄清楚如何在保存后的回调中告诉数组中的变化。以下是我正在使用的代码示例:

class User < ActiveRecord::Base
  has_many :user_maps, :dependent => :destroy
  has_many :subusers, :through => :user_maps, :dependent => :destroy

  has_many :inverse_user_maps, :class_name => "UserMap", :foreign_key => "subuser_id"
  has_one :parent, :through => :inverse_user_maps, :source => :user

  after_save :remove_subusers

  def remove_subusers
    if self.subuser_ids_were != self.subuser_ids
      leftover = self.subuser_ids_were - self.subuser_ids

      leftover.each do |subuser|
        subuser.destroy
      end
    end
  end
end

class UserMap < ActiveRecord::Base
  belongs_to :user
  belongs_to :subuser, :class_name => "User"
end

我正在使用after_save回调删除子用户,因为我无法通过user_maps获取依赖性销毁功能。有没有人对这种方法有任何想法?

谢谢!

2 个答案:

答案 0 :(得分:0)

虽然不是严格地回答你的问题,但我认为你可能会得到:依赖=&gt; :如果你尝试以下方法,就破坏工作......

class User < ActiveRecord::Base
  has_many :user_maps, :dependent => :destroy
  has_many :subusers, :through => :user_maps # removing the :dependent => :destroy option
end

class UserMap < ActiveRecord::Base
  belongs_to :user
  belongs_to :subuser, :class_name => "User", :dependent => :destroy # add it here
end

移动:dependent =&gt; :对UserMap模型中的belongs_to关联销毁选项,通过UserMap#destroy方法设置级联删除。换句话说,调用User#destroy会为每个UserMap记录调用UserMap#destroy,而后者又会调用sub_user.destroy作为其sub_user记录。

修改

由于上面的解决方案不起作用,我的下一个建议是添加一个回调给user_maps关联,但是这附带一个警告我将在

之后添加
class User < ActiveRecord::Base
  has_many :user_maps, :dependent => :destroy, :before_remove => :remove_associated_subuser

  def remove_associated_subuser(user_map)
    user_map.subuser.destroy
  end
end

<强>警告

1)使用before_remove回调意味着如果回调出错,将不会调用user_map.destroy函数

2)您必须使用User类上的方法销毁您的UserMap记录,例如......

# this will fire the callback
u = User.first
u.user_maps.destroy(u.user_maps.first)

# this WONT fire the callback
UserMap.first.destroy

考虑到所有因素,这会让我感到紧张。我首先尝试修改你的代码,使关联少一点耦合到相同的表,所以:dependent =&gt; :destroy选项可以工作,如果你不能这样做,就可以在数据库中添加一个级联删除约束,至少你的关联将被删除,无论你在rails应用程序中的哪个/如何销毁它。

答案 1 :(得分:0)

您可以按http://ar.rubyonrails.org/classes/ActiveRecord/Dirty.html

中的建议使用脏模块访问器Determine what attributes were changed in Rails after_save callback?

在您的情况下,您对after_save的处理程序将有权访问subusers_change,这是一个包含两个元素的数组,第一个是前一个值,第二个是新值。