在 Rails 中创建新模型实例时发送电子邮件的最佳方式?
我有一个具有以下模型的应用程序:User
、Task
和 Assignment
。每个分配属于
一个用户和一个任务(或者换句话说,任务通过分配分配给用户)。
用户完成任务后,分配将被标记为完成,并且应用程序会立即创建新的分配(或者换句话说,将任务分配给其他人)。
创建此新作业后,我想立即向新受让人发送一封电子邮件。我知道我可以通过以下三种方式之一执行此操作:
- 在我的控制器中显式发送电子邮件。
- 在作业模型的回调中发送电子邮件。
- 在分配模型上创建观察者并在
after_create
中发送电子邮件。
人们认为这些选项中哪一个最好,为什么? #1 对我来说似乎很糟糕,因为我不想记住在可能完成作业的每个操作中发送它。我听过一些人说 Rails 观察员很糟糕,应该避免,但我不确定他们是否是我应该信任的人。还有其他意见吗?
I have an app with the following models: User
, Task
, and Assignment
. Each Assignment belongs_to
a User and a Task (or in other words, a Task is assigned to a User via an Assignment).
Once a User completes a Task, the Assignment is marked as complete, and the app immediately creates a new Assignment (or in other words, assigns the task to someone else).
Immediately after creating this new Assignment, I want to send an email to the new assignee. I know I can do this one of three ways:
- Explicitly send the email in my controller.
- Send the email in a callback on the Assignment model.
- Create an observer on the Assignment model and send the email in
after_create
.
Which of these options do people think is best, and why? #1 seems bad to me, because I don't want to have to remember to send it in every action that might complete an Assignment. I've heard a couple people say that Rails observers are bad and should be avoided, but I'm not sure if they're people I should trust or not. Any other opinions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你是对的,第一种方法不是一个好方法。出于几个原因,观察员是我的首选方式。
首先,如果您使用 TDD(测试驱动开发),您可以关闭观察者以更纯粹地测试模型,而无需每次创建都触发邮件程序创建。然后您可以分别对邮件程序和观察者进行单元测试。
其次,分离回调的想法创建了更清晰的代码。回调实际上并不是模型的一部分,它们是事件。您的模型包含运行自身所需的函数和属性,并且回调(使用观察者实现)是单独的事件处理程序。
也就是说,我不认为你的第二个选择是“坏”或不太专业。只要是在模型级别,而不是控制器或(更糟糕的)视图,任何一种方式都有效。
You're right, the first way isn't a good approach. Observers are my preferred way to go, for a couple reasons.
First, if you use TDD (test-driven development) you can shut off observers to more purely test the model without every creation firing off a mailer creation. Then you can unit test the mailer and observer separately.
Second, the idea of separating callbacks creates cleaner code. Callbacks aren't really part of your model, they are events. Your model contains the functions and attributes necessary to run itself, and the callbacks (implemented with observers) are separate event handlers.
That said, I don't think your second option is "bad" or less professional. Either way works as long as it's at the model level, instead of controllers or (even worse) views.
我会选择观察者,因为它们可以减少模型/控制器代码中的混乱,并且我认为使用它们没有任何缺点...
iirc 在保存电子邮件后发送电子邮件甚至是活动记录观察者文档中的一个示例
i would go for observers as they reduce clutter in your model / controller code and i can think of no downside in using them ...
iirc sending an email after save email is even an example in the active record observers documentation
你也可以做一些事情的组合。您可以将观察者用于一项操作,如果只有一封电子邮件用于另一项操作,您可以使用选项#1。
您听说过 acts_as_state_machine 或任何其他类似的解决方案吗?
http://github.com/rubyist/aasm
它们允许您定义每个对象的状态并状态变化可能会发生不同的事情。
如果您需要这么多,这使您可以在发送内容时拥有所需的逻辑。可能有点矫枉过正,但确实很方便。我建议是因为您希望在任务“完成”时发送一封电子邮件,这听起来可能是任务模型中的一种状态或状态列。
You can also do a combination of things. You could use observers for one action, and if there is just a single email for one other action you could use option #1 for it.
Have you heard of acts_as_state_machine, or any other similar solutions?
http://github.com/rubyist/aasm
They allow you to define a state of each object and different things that can happen with state changes.
This allows you to have as much logic as you need about when things are sent, if you need this much. Can be overkill, but can be really handy. I suggest because you want an email sent when a task is 'completed' which sounds like it may be a type of state or status column in your Task model.
最后,我喜欢这个实现 http://www.scottw.com/resque-mail -队列宝石
In the end, I like this implementation http://www.scottw.com/resque-mail-queue-gem