ActionMailer最佳实践:调用模型或控制器中的方法?
发送电子邮件通常是在对模型执行操作后调用的,但电子邮件本身是一个视图操作。 我正在寻找您如何思考要问自己哪些问题来确定将操作邮件程序方法调用放在哪里。
我已经看到/使用过它们:
- 在模型方法中 - 相关但独立的关注点耦合不良?
- 在模型的回调中(例如 after_save) - 据我目前的知识水平所知,最好的分离。
- 在控制器操作中 - 只是感觉不对,但是在某些情况下这是构建代码的最明智的方法吗?
如果我想知道如何编程,我需要像程序员一样思考,因此学习如何思考特定的编程解决方案值得我独自编码数月。 谢谢你!
Sending an email is usually called after an action on a model, but the email itself is a view operation. I'm looking for how you think about what question(s) to ask yourself to determine where to put the action mailer method call.
I've seen/used them:
- In a model method - bad coupling of related but seperate concerns?
- In a callback in the model (such as after_save) - best separation as far as I can tell with my current level of knowledge.
- In the controller action - just feels wrong, but are there situations were this would be the smartest way to structure the code?
If I want to know how to program I need to think like a programmer, so learning how you go about thinking through particular programming solutions is worth months of coding on my own in isolation. Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
迟到的答案,但我想对这个主题进行合理化解释:
通常,在网络应用程序中,您希望发送电子邮件作为对客户的直接反应。 或者作为后台任务,以防我们谈论时事通讯/通知邮件之类的事情。
该模型基本上是一个数据存储映射器。 其逻辑应将数据处理/通信与数据存储处理封装在一起。 因此,插入与其无关的逻辑有点棘手,而且在大多数情况下是错误的。 让我们举个例子:用户注册一个帐户,应该会收到一封确认电子邮件。 在这种情况下,人们可以说,确认电子邮件是创建新帐户的直接结果。 现在,不要在 Web 应用程序中执行此操作,而是尝试在控制台中创建用户。 在这种情况下触发回调听起来是错误的,对吧? 所以,回调选项被划掉了。 我们还应该将方法写在模型中吗? 好吧,如果它是用户操作/输入的直接影响,那么它应该保留在该工作流程中。 成功创建用户后,我会将其写入控制器中。 直接地。 无论如何,在要在控制器中调用的模型中复制此逻辑都会增加不必要的模块化以及来自 Action Mailer 的 Active Record 模型的依赖性。 尝试考虑在许多应用程序上共享模型,其中一些应用程序不希望使用 Action Mailer。 由于上述原因,我认为邮件程序调用应该在有意义的地方,而通常模型不是那个地方。 试着给我举一些例子。
Late answer, but I want to rationalize on the subject:
Usually, in a web app, you want to send emails either as a direct reaction to a client. Or as a background task, in case we're talking about a newsletter/notification mail sort of thing.
The model is basically a data storage mapper. Its logic should encapsulate data-handling/communication with data storage handling. Therefore, inserting logic which does not relate to it is a bit tricky, and in most cases wrong. Let us take the example: User registers an account and should receive a confirmation email. In this case one could say, the confirmation email is a direct effect of the creation of a new account. Now, instead of doing it in the web app, try to create a user in the console. Sounds wrong to trigger a callback in that case, right? So, callback option scratched. Should we still write the method in the model? Well, if it's a direct effect of a user action/input, then it should stay in that workflow. I would write it in the controller after the user was successfully created. Directly. Replicating this logic in the model to be called in the controller anyways adds unnecessary modularity, and dependency of an Active Record model from Action Mailer. Try to consider sharing the model over many apps, in which some of them don't want Action Mailer for it. For the stated reasons, I'm of the opinion that the mailer calls should be where they make sense, and usually the model is not that place. Try to give me examples where it does make.
嗯,要看情况。
我已经使用了所有这些选项以及您关于“为什么我应该把它放在哪里?”的观点。 很好。
如果我希望每次以某种方式更新模型时都会发生这种情况,那么我会将其放入模型中。 甚至可能在模型的回调中。
有时你只是发出一份报告; 没有任何更新。 在这种情况下,我通常会获得带有发送报告的索引操作的资源。
如果邮件程序与正在更改的模型并不真正相关,我可以考虑将其放入回调中。 我不经常这样做。 我更有可能将其封装在模型中。 我曾经这样做过,只是不经常这样做。
Well, depends.
I've used all of those options and your point about 'why should I put this where?' is good.
If it's something I want to happen every time a model is updated in a certain way, then I put it in the model. Maybe even in a callback in the model.
Sometimes you're just firing off a report; there's no updating of anything. In that case, I've normally got a resource with an index action that sends the report.
If the mailer isn't really related to the model that's being changed, I could see putting it in a callback. I don't do that very often. I'd be more likely to still encapsulate it in the model. I've done it, just not very often.
我知道已经有一段时间了,但最佳实践永远不会消亡,对吧? :)
根据定义,电子邮件是异步通信(确认电子邮件除外,但即使是这封电子邮件,在必须确认之前留下延迟也应该是最佳实践)。
因此,在我看来,最合乎逻辑的发送方式是:
Rails 的问题是它没有太多的回调(例如在 JS 中):我个人觉得这样的代码很肮脏:
所以,如果你真的想像程序员一样思考,这个想法将是在您的应用程序中设置一些自定义回调系统。
例如。
或者甚至在应用程序中创建事件系统也是一个不错的解决方案。
但最终这些解决方案在时间上相当昂贵,因此人们最终在操作之后内联编写它,
这是同步编程中最接近回调的方式,结果邮件程序到处调用(在模型中和在控制器)。
I'm aware it's been a while but best practices never die, right? :)
Email is by definition asynchronous communication (except for confirmation email, but even this one it should be a best practice to leave a delay before having to confirm).
Hence in my opinion, the most logical way to send it is :
Problem in Rails is that it is not too many callbacks (as in JS for instance): I personnaly find it dirty to have code like:
So, if you really want to think like a programmer, the idea would be to set up some custom callback system in your app.
Eg.
Or even creating an event system in your app would be a decent solution.
But in the end those solutions are pretty expensive in time so people end-up writing it inline after the action
which is the closest fashion to callback in synchronous programming and results having Mailers call everywhere (in
Model
and inController
).控制器成为邮件发送者的好地方有几个原因:
There's several reasons why controllers are a good place for the mailers: