Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Mailer Best Practice - controller or after_create callback? [closed]

In common Ruby on Rails 3/4 apps, there are two options to deliver mail after the creation of a model:

1) Send the mail directly from the controller's create action

#listings_controller.rb

def create
    @listing.create(params[:listing])
    if @listing.save
        ListingMailer.new_listing_notice(@listing).deliver
        format.html {redirect_to @listing}
        ...
    end
end

or 2) Send the mail from a Model Callback

#listing.rb


class Listing
    after_create :notify
    ...
    def notify
        ListingMailer.new_listing_notice(self).deliver
    end
end

Is there a current consensus about which way is better? Sending from the controller gives more control, but if a mail will always be sent is there any reason not to use the callback? Is this mostly a question of style, or are there other important concerns?

like image 832
Erik Kastman Avatar asked May 22 '14 04:05

Erik Kastman


1 Answers

Generally, it's much more difficult to maintain code that has after_* hooks in models. There are, of course some cases, when using a callback is very reasonable (computing a checksum, for instance, should be done all the time in some applications), but those cases are exceptions to the rule.

In your example with the email, here's some drawbacks of the callback approach:

The mailer interface and the Listing model change for different reasons (Single Responsibility Principle).

For instance, you would like your emails to be sent using a special queue. The interface of communicating with the queue should not, in any way, affect the way the Listing model is built.

Your application doesn't need emailing all the time.

Emailing is just one of the means of interacting with the outside world. Not all of the business logic will always require to be tied to the outside world. One of the examples, as apneadiving mentioned is import. Another example is the console interface (would you like to be sent an email when you're playing with the rails console?)

Testing is difficult.

This is more of a result of 1 and 2, but testing after hooks is increasingly difficult as time passes. The need of mocking the mailer while testing the Listing model makes the test unclear and more difficult to maintain whenever something changes.

like image 163
Ivan Zarea Avatar answered Nov 25 '22 10:11

Ivan Zarea