Rails的ActiveRecord的3.2:如何跳过子模型before_delete回调? [英] Rails ActiveRecord 3.2: How to skip before_delete callback in child model?
问题描述
我在工作中的Rails 3.2.16。在我的应用程序,一个账户HAS_MANY用户。一个账户必须始终具有管理用户,所以你不能消灭他们。这需要的是护理:
I'm working in Rails 3.2.16. In my app, an account has_many users. An account must always have admin users, so you can't destroy them. This takes care of that:
class Account < ActiveRecord::Base
has_many :users, :dependent => :destroy
end
class User < ActiveRecord::Base
before_destroy :check_if_admin
def check_if_admin
false if self.is_admin
end
end
不过,当你摧毁整个帐户,该管理员应,以及销毁。相反,当我打电话 @ account.destroy
从控制器,用户#before_delete
回调prevents管理员用户被破坏。
However, when you destroy the whole account, the admins should be destroyed as well. Instead, when I call @account.destroy
from the controller, the User#before_delete
callback prevents the admin users from being destroyed.
我知道我可以叫 @ account.delete
跳过回调,但我的理解是,:依赖=&GT; :摧毁
本身就是一个回调,这样只会删除该帐户,而不是用户
I know I could call @account.delete
to skip callbacks, but my understanding is that the :dependent => :destroy
is itself a callback, so that would only delete the account, not the users.
有没有办法回调里面知道我从哪里来,如:
Is there a way inside the callback to know where I came from, e.g.
def check_if_admin
return if [I'm doing an Account dependent delete]
false if self.is_admin
end
还是我不得不手动删除
在用户销毁
荷兰国际集团的帐户?
or do I have to manually delete
the users before destroy
ing the account?
推荐答案
通过这个答案的帮助下,我找到了该溶液中。我们的想法是暂时关闭特定的子回调,而破坏了父母。请注意,我不得不添加:prePEND =&GT; :得到真正
选项我定制的回调重新加入连锁的前
With the help of this answer, I found this solution. The idea is to temporarily turn off the specific child callback while destroying the parent. Note that I had to add the :prepend => :true
option to get my custom callback re-added to the front of the chain.
class Account < ActiveRecord::Base
before_destroy :disable_user_check_if_admin
before_destroy :enable_user_check_if_admin
has_many :users, :dependent => :destroy
def disable_user_check_if_admin
User.skip_callback(:destroy, :before, :check_if_admin)
end
def enable_user_check_if_admin
User.set_callback(:destroy, :before, :check_if_admin), :prepend => :true
end
end
class User < ActiveRecord::Base
before_destroy :check_if_admin
has_many :contacts, :dependent => :restrict
def check_if_admin
false if self.is_admin
end
end
没有:prePEND =&GT; :真正的
,我遇到了麻烦,因为我的用户模型还的has_many:联系人:依赖=&GT; :限制
。问题是, skip_callback
实际删除回调和 set_callback
再增加了回调的在年底回调链的。使用:prePEND =&GT; :真正的
,我可以插入我的自定义 before_destroy:check_if_admin
回调在链的最前端。请参阅文档和源$ C $ C <一个href="http://api.rubyonrails.org/v3.2.16/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-set_callback"相对=nofollow>这里。
Without :prepend => :true
, I ran into trouble because my User model also has_many :contacts, :dependent => :restrict
. The problem is that, skip_callback
actually deletes the callback and set_callback
re-adds the callback at the end of the callback chain. Using :prepend => :true
, I was able to insert my custom before_destroy :check_if_admin
callback at the front of the chain. See docs and source code here.
替代解决方案(未使用)
虽然我打回调序列中,我尝试了不同的解决方案,离开回调完好。从这个答案借用,我用了一个访问的帐户,让我检查时,它被删除:
While I was fighting the callback sequence, I tried a different solution that leaves the callbacks intact. Borrowing from this answer, I used an accessor on Account to let me check when it is being deleted:
class Account < ActiveRecord::Base
before_destroy :disable_user_check_if_admin
before_destroy :enable_user_check_if_admin
has_many :users, :dependent => :destroy
attr_accessor :destroying
def disable_user_check_if_admin
self.destroying = true
end
def enable_user_check_if_admin
self.destroying = false
end
end
class User < ActiveRecord::Base
before_destroy :check_if_admin
has_many :contacts, :dependent => :restrict
def check_if_admin
return if self.account.destroying
false if self.is_admin
end
end
该做的工作,但它并没有闻的权利被设置和检查这样的一个标志,所以我又回到了跳跃/套回调使用:prePEND =&GT; :真正的
This did work but it doesn't "smell" right to be setting and checking a flag like this, so I went back to the skip/set callback using :prepend => :true
.
这篇关于Rails的ActiveRecord的3.2:如何跳过子模型before_delete回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!