确定在 Rails after_save 回调中从数组中删除了哪些 id?
我试图弄清楚如何知道保存后回调中数组中发生了什么变化。这是我正在使用的代码示例:
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 获取依赖的销毁功能。有没有人有任何想法来做到这一点?
谢谢!
I am trying to figure out how i can tell what has changed in an array in the after save callback. Here is an example of code i am using:
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
I am removing the subusers with the after_save callback because i could not get the dependent destroy feature to work through user_maps. Does anyone have any ideas on a way to do this?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 Dirty 模块访问器 http://ar.rubyonrails.org/classes/ActiveRecord /Dirty.html 按照 确定 Rails after_save 回调中更改了哪些属性?
在您的情况下,
after_save
的处理程序将有权访问subusers_change
,它是一个由两个元素组成的数组,第一个是以前的值,第二个是新的价值。You can use the Dirty module accessors http://ar.rubyonrails.org/classes/ActiveRecord/Dirty.html as suggested in Determine what attributes were changed in Rails after_save callback?
In your case the handler you have for
after_save
will have access tosubusers_change
which is an array of two elements, first being the previous value and second being the new value.虽然严格来说不是您问题的答案,但我认为您也许能够得到 :dependent =>如果您尝试以下操作,则破坏工作...
通过移动 :dependent =>在 UserMap 模型中,您可以通过 UserMap#destroy 方法设置级联删除。换句话说,调用 User#destroy 将为每个 UserMap 记录调用 UserMap#destroy,进而为其 sub_user 记录调用 sub_user.destroy。
编辑
由于上述解决方案不起作用,我的下一个建议是向 user_maps 关联添加回调,但这会附带一个警告,我将在
警告
之后添加1) 使用 before_remove 回调意味着,如果回调出现错误,则不会调用 user_map.destroy 函数
2) 您必须使用 User 类上的方法销毁 UserMap 记录,例如...
全部考虑到这一点会让我紧张。我首先尝试修改您的代码以使关联与相同表的耦合程度降低一些,因此 :dependent =>; :destroy 选项可以工作,如果你不能这样做,请在数据库中添加级联删除约束,至少这样你的关联将始终被删除,无论你在 Rails 应用程序中的何处/如何销毁它。
although not strictly the answer to your question, I think you maybe able to get :dependent => :destroy working if you try the following...
By moving the :dependent => :destroy option to the belongs_to association in the UserMap model you set up a cascading delete via the UserMap#destroy method. In other words, calling User#destroy will call UserMap#destroy for each UserMap record, which will in turn call sub_user.destroy for its sub_user record.
EDIT
Since the solution above didn't work, my next suggestion would be to add a callback to the user_maps association, however this comes with a warning that I will add after
WARNINGS
1) Using a before_remove callback will mean that the user_map.destroy function won't be called if there is an error with the callback
2) You will have to destroy your UserMap record using the method on the User class for example...
All things considered, this would make me nervous. I would first try modifying your code to make the associations a little less coupled to the same tables, so the :dependent => :destroy option can work, and if you can't do that, add a cascade delete constraint on to the database, at least then your associations will always be removed regardless of where / how you destroy it in your rails app.