2009-02-03 41 views
18

发送电子邮件通常在对模型执行操作后调用,但电子邮件本身是查看操作。我正在寻找你如何考虑问什么问题来问问自己,以确定在哪里放置动作邮件程序方法调用。ActionMailer最佳实践:在模型或控制器中调用方法?

我见过/使用它们:

  • 在模型方法 - 相关,但单独的担忧糟糕的耦合?
  • 在模型中的回调(比如after_save) - 根据我目前的知识水平可以看出最佳分离。
  • 在控制器动作 - 只是感觉不对,但是有没有这种情况是最聪明的方式来构造代码?

如果我想知道如何编程,我需要这样想一个程序员,所以学习你如何通过特定的编程解决方案的想法是孤立我自己编码的身价个月。谢谢!

回答

12

晚的答案,但我要理顺这个话题:

通常,在一个Web应用程序,你要发送的邮件无论是作为一个客户的直接反应。或作为背景任务,以防我们正在谈论通讯/通知邮件类的事情。

该模型基本上是一个数据存储映射器。其逻辑应该将数据处理/通信与数据存储处理封装在一起。因此,插入与其无关的逻辑有点棘手,并且在大多数情况下是错误的。让我们举个例子:用户注册一个帐户,并应该收到一封确认邮件。在这种情况下,人们可以说,确认电子邮件是创建新帐户的直接结果。现在,不要在Web应用程序中执行此操作,请尝试在控制台中创建一个用户。在这种情况下触发回拨听起来不对,对吧?所以,回调选项划痕。我们是否还应该在模型中编写该方法?那么,如果它是用户操作/输入的直接影响,那么它应该保留在该工作流程中。在成功创建用户后,我会将它写入控制器。直。在控制器中调用模型中的这个逻辑反正会增加不必要的模块性,并且增加了Action Mailer中Active Record模型的依赖性。尝试考虑在许多应用程序中共享模型,其中一些应用程序不需要Action Mailer。由于陈述的原因,我认为邮件的呼叫应该是他们有意义的地方,通常这个地方的型号是而不是。试着给我举例说明它的作用。

+1

我看错了吗,还是你自相矛盾? “直接在用户成功创建后,我会将它写入控制器。”那么后来“由于陈述的原因,我认为邮件调用应该是他们有意义的地方,通常这个模型就是那个地方。” – Cameron 2014-09-17 22:26:06

4

嗯,要看。

我已经使用了所有这些选项以及你为什么要把它放在哪里?很好。

如果这是我希望每次以某种方式更新模型时发生的事情,那么我就把它放在模型中。甚至可能在模型中回调。

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

如果邮件程序与正在更改的模型没有真正关联,则可以将其置于回调中。我不经常这样做。我更有可能仍将其封装在模型中。我做到了,只是不经常。

1

我知道这是一段时间,但最佳实践永远不会死,对吧?:)

电子邮件按定义异步通信(除了确认电子邮件,但即使是这一个,它应该是一个最好的做法,以在必须确认之前留下延迟)。

因此,在我看来,送它最合理的方式是:

    在后台动作
  • (使用Sidekiqdelayed_job)在回调方法
  • :“嘿,这个动作成功完成,也许我们现在可以告诉世界吗?“

问题在Rails的是,它是太多回调没有(如JS为例):我personnaly觉得脏有这样的代码:

after_save :callback 

def callback 
    if test_that_is_true_once_in_the_objects_life 
    Mailer.send_email() 
    end 
end 

所以,如果你真的想想像一个程序员,这个想法是在你的应用程序中设置一些自定义回调系统。

例如,

def run_with_callback(action, callback_name) 
    if send(action) 
    delay.send(callback_name) 
    end 
end 

甚至creating an event system in your app将是一个体面的解决方案。

但最终的解决方案是相当昂贵的时间,使人们最终行动了

def activate 
    [...] 
    user.save 
    Mailer.send_mail 
    respond_to 
    [...] 
end 

这是最接近时尚同步编程回调,并具有邮件程序调用处处结果后直列写它(在ModelController)。

0

有几个原因控制器是为邮寄的好去处:

  • 电子邮件,什么都没有做一个模型。
  • 如果您的电子邮件依赖于不知道彼此的几个模型。
  • 将模型提取到API不应该意味着重新实现邮件程序。
  • 邮件内容由您不想传递给模型的请求变量确定。
  • 如果您的商业模式需要大量不同的电子邮件,则模型回调可以堆叠。
  • 如果电子邮件不依赖于模型计算的结果。
相关问题