在我的Rails应用中,我有一些 after_commit
... on: :update
回调,负责在用户更新账户设置后做一些工作。
麻烦的是,这些回调在用户注销时被触发。我检查了用户的更新情况,通过调用 self.previous_changes
这就是输出。
=> {"remember_created_at"=>[Wed, 06 May 2020 20:32:09 UTC +00:00, nil], "updated_at"=>[Thu, 07 May 2020 14:52:42 UTC +00:00, Thu, 07 May 2020 14:54:40 UTC +00:00]}
所以,你可以看到,注销清除了 "remember_created_at"
和更新 "updated_at"
.
我可以在用户身上建立一个方法,叫做 is_logging_out?
检查这两个改变了的属性并返回true,但这感觉像黑客一样,我想知道是否有更优雅的方法来做这件事。
(如果有关系的话,我使用的是devise v3.5.10)
模型回调有这个缺点。我强烈提倡不使用模型回调,而使用Decorators或显式调用。然而,如果你确定你需要这个回调,那么为什么不尝试跳过这个回调,除非 remember_created_at
不是nil?
def your_callback_method
return unless remember_created_at
#do stuff
end
你可以在回调方法中跳过它,或者在回调方法中添加 if: -> { record.remember_created_at }
至 after_commit
声明
请不要添加一个名为 is_logging_out?
中,因为这不是模型的责任。模型不应该依赖于用户正在进行的操作是什么。
你真的想一开始就使用模型回调吗?它们的本质是黑客行为,而且通常会变得越来越难以控制它们何时何地被启动。
如果你只是覆盖控制器,你就会清楚地知道这个逻辑将在哪里被触发,它不会减慢你的测试速度,也不会在以后产生更多意想不到的错误。
class UsersController < Devise::SessionsController
def update
super do |user|
# do something awesome
end
end
end
devise_for :users, controller: {
registrations: 'my_sessions'
}