Syl*_*Syl 2 model-view-controller ruby-on-rails callback
我有一个模型,当它处于特定状态时,需要一些额外的数据,然后发送邮件.
为此,我有一个前验证回调说
"我处于这种需要数据的状态,我需要更多数据吗?不是吗?那么我将改变我的状态并发送邮件".
这种状态是每晚由cron rake触发的,有时候不需要数据,所以它应该尽快发送邮件.稍后收集数据时,将触发回调并且邮件将继续运行.
我已阅读并被告知邮件应仅从控制器发送.但这里的意思是我需要在我的控制器和我的耙子中发送邮件.
为什么从回调中发送邮件"不好"?
从一个地方开始将邮件发送到两个不同的地方不是一个坏主意吗?
为什么会这么糟糕?
使用ActiveRecord :: Observer.这是一个完美的用例,因为邮件逻辑可能既不属于您的模型,也不属于控制器.
class WelcomeEmailObserver < ActiveRecord::Observer
observe :user
def after_create(user)
if user.purchased_membership?
GreetingMailer.welcome_and_thanks_email(user).deliver
else
GreetingMailer.welcome_email(user).deliver
end
end
end
# app/models/user.rb
class User
end
# config/application.rb
class Application < Rails::Application
config.active_record.observers = :welcome_email_observer
end
Run Code Online (Sandbox Code Playgroud)
从这里偷来的例子.
我还建议你让观察者无国籍,否则很难调试它们.仅将它们用于与第三方API,电子邮件或其他与您的应用程序无关的内容的回调.
我建议你使用无偷窥者来测试它们.不要将观察者测试与模型测试隔离开来 - 这没有多大意义,但一定要在有和没有观察者的情况下测试模型.使用此辅助宝石,您可以定位您喜欢的观察者并打开或关闭它.
对观察者实施单一责任原则,不要将它们与模型联系起来.让持久性逻辑远离观察者.使用模型回调来解决与持久性相关的问题.
另外,我想警告你在使用像Sidekiq这样的东西时要小心观察者.它有时比ActiveRecord回调更快,因此您应该使用after_commit回调来避免冲突.
ActiveRecord :: Observers将在Rails 4.0中弃用,因为它们被提取到gem中.但是,您仍然可以使用它们,但似乎Rails核心团队强制将所有内容提取到单一职责的类中.选择使用方法取决于您的口味.
观察者使一切都不那么明确,而且确定测试更加复杂.如果你知道自己在做什么,他们仍然可以成为优秀的OO公民.
使用普通的旧红宝石物体对我来说似乎更像DCI,这是一个很大的优点,因为它更清楚地表达了你的意图.