首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ActionMailer最佳实践:在模型中调用方法还是在控制器中调用?

ActionMailer最佳实践:在模型中调用方法还是在控制器中调用?
EN

Stack Overflow用户
提问于 2009-02-03 19:40:37
回答 4查看 5.9K关注 0票数 24

发送电子邮件通常是在模型上的操作之后调用的,但电子邮件本身是一个视图操作。我正在寻找你如何思考什么问题来询问自己,以确定将操作邮件程序方法调用放在哪里。

我见过/用过它们:

模型方法中的

  • -相关但独立的关注点的糟糕耦合?模型中的回调(如after_save)中的
  • -据我目前的知识水平所知,最佳分离。控制器操作中的
  • -只是感觉不对,但是否存在这样的情况,即这是构建代码的最聪明的方式?

如果我想知道如何编程,我需要像程序员一样思考,所以学习如何思考特定的编程解决方案是值得我独自编码几个月的。谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-24 17:35:11

回答晚了,但我想在这个问题上说得更合理一些:

通常,在web应用程序中,您希望发送电子邮件作为对客户的直接反应。或者作为后台任务,以防我们正在讨论时事通讯/通知邮件之类的事情。

该模型基本上是一个数据存储映射器。其逻辑应将数据处理/通信与数据存储处理封装在一起。因此,插入与之无关的逻辑有点棘手,而且在大多数情况下都是错误的。让我们举个例子:用户注册了一个帐户,应该会收到一封确认电子邮件。在这种情况下,可以说,确认电子邮件是创建新帐户的直接影响。现在,尝试在控制台中创建用户,而不是在web应用程序中创建用户。在这种情况下触发回调听起来是不对的,对吧?所以,回调选项被划掉了。我们还应该在模型中编写方法吗?好吧,如果它是用户操作/输入的直接影响,那么它应该留在工作流程中。在成功创建用户后,我会将其写入控制器。直接了当。无论如何,在要在控制器中调用的模型中复制此逻辑会增加不必要的模块性,以及对Action Mailer中的活动记录模型的依赖性。尝试考虑在许多应用程序中共享该模型,其中一些应用程序不需要Action Mailer。出于上述原因,我认为邮件程序调用应该放在有意义的地方,而模型通常不在那个地方。试着给我举个例子,它确实很有用。

票数 15
EN

Stack Overflow用户

发布于 2009-02-03 21:42:52

嗯,要看情况了。

我已经使用了所有这些选项和你关于“为什么我应该把这个放在哪里?”的观点。是好的。

如果这是我希望每次以某种方式更新模型时发生的事情,那么我会将其放入模型中。甚至在模型中的回调中也是如此。

有时,您只是发布一份报告;没有任何更新。在这种情况下,我通常会得到一个带索引操作的资源来发送报告。

如果邮件程序与正在更改的模型并不相关,我可以将其放入回调中。我并不经常这样做。我更有可能仍然将其封装在模型中。我曾经这样做过,只是不是很经常。

票数 4
EN

Stack Overflow用户

发布于 2014-10-16 17:27:04

我知道已经有一段时间了,但最佳实践永远不会消亡,对吧?:)

根据定义,电子邮件是异步通信(除了确认电子邮件,但即使是这封电子邮件,也应该是在确认之前留下延迟的最佳实践)。

因此,在我看来,最合乎逻辑的发送方式是:

在后台执行回调操作(使用Sidekiqdelayed_job)

  • in回调方法:“嘿,此操作已成功完成,也许我们现在可以告诉全世界了?”

Rails中的问题是它没有太多的回调函数(例如在JS中):我个人觉得像这样的代码是很脏的:

代码语言:javascript
复制
after_save :callback

def callback
  if test_that_is_true_once_in_the_objects_life
    Mailer.send_email()
  end
end

因此,如果你真的想要像程序员一样思考,那么你可以在你的应用程序中设置一些自定义的回调系统。

例如:

代码语言:javascript
复制
def run_with_callback(action, callback_name)
  if send(action)
    delay.send(callback_name)
  end
end

或者甚至creating an event system in your app将是一个不错的解决方案。

但最终,这些解决方案在时间上是相当昂贵的,所以人们最终还是在操作之后内联编写它

代码语言:javascript
复制
def activate
  [...]
  user.save
  Mailer.send_mail
  respond_to 
  [...]
end

在同步编程中,这是最接近回调的方式,结果让邮件程序到处调用(在ModelController中)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/508587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档