我试图弄清楚如何在保存后的回调中告诉数组中的变化。以下是我正在使用的代码示例:
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获取依赖性销毁功能。有没有人对这种方法有任何想法?
谢谢!
答案 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
,这是一个包含两个元素的数组,第一个是前一个值,第二个是新值。