Rails:在 after_commit 中调用相同的方法来创建、更新、删除,但根据某些标志做不同的事情
Posted
技术标签:
【中文标题】Rails:在 after_commit 中调用相同的方法来创建、更新、删除,但根据某些标志做不同的事情【英文标题】:Rails: call same method in after_commit for create, update, delete but do separate things based on certain flags 【发布时间】:2022-01-12 12:41:00 【问题描述】:我想根据以下场景在 3rd 方服务上创建和删除用户
在第 3 方创建用户
在应用程序中创建用户时 从inactive
标记为active
(我的用户模型上有一个名为is_active
的列)
删除第三方用户
当用户从应用程序中删除时 标记为inactive
看起来我可以使用after_commit
回调,但我如何在after_commit
中识别该操作是create
、update
或delete
对此的任何帮助都会有所帮助。
【问题讨论】:
您可以使用:on
选项指定回调只应由特定操作触发:after_commit :do_foo, on: :create
、after_commit :do_bar, on: :update
、after_commit :do_foo_bar, on: [:create, :update]
【参考方案1】:
不要为此使用回调——你会后悔的。 回调的主要问题是:
没有上下文 - 您实际上不知道应用程序中发生了什么。 很难控制回调实际触发的时间 - 更重要的是,当您不希望它触发时(例如在加载固定装置时)。 这让模型承担了太多责任。 您无法独立于创建/更新/销毁记录来测试回调逻辑。当您似乎也在处理第三方 API 时,我真的不能低估这一点。当您触及应用程序边界时使用隐式机制(如回调)是一个非常糟糕的主意。通过单一方法管道传输所有内容的整个想法也不合理。
相反,您可以使用service objects 等模式来处理模型的“转换”。
class UserCreationService
def initialize(user)
@user = user
end
def perform
# do something with @user
end
end
class UserInactivationService
def initialize(user)
@user = user
end
def perform
# do something with @user
end
end
它们只做一项工作并且易于测试,并且只有在您明确希望它们时才会触发。 ActiveJob 实际上就是这种模式的一个例子。
【讨论】:
感谢@max 的回复。所以我需要显式调用服务,例如,当创建用户时,在RegistrationController
我需要调用在第 3 方创建用户的服务
是的,这就是重点。以上是关于Rails:在 after_commit 中调用相同的方法来创建、更新、删除,但根据某些标志做不同的事情的主要内容,如果未能解决你的问题,请参考以下文章