Search code examples
ruby-on-railsemailmodelcallbackobserver-pattern

Best way to send an email upon creation of a new model instance in 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:

  1. Explicitly send the email in my controller.
  2. Send the email in a callback on the Assignment model.
  3. 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?


Solution

  • 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.