Rails Mailer最佳实践 - 控制器或after_create回调?

时间:2014-05-22 04:24:34

标签: ruby-on-rails email

在常见的Ruby on Rails 3/4应用程序中,有两种方法可以在创建模型后传递邮件:

1)直接从控制器发送邮件创建操作

#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

2)从模型回调中发送邮件

#listing.rb


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

目前对哪种方式更好有共识?从控制器发送可以提供更多控制,但如果始终发送邮件,是否有任何理由不使用回调?这主要是风格问题,还是有其他重要问题?

1 个答案:

答案 0 :(得分:13)

通常,维护模型中具有after_*挂钩的代码要困难得多。当然,在某些情况下,使用回调非常合理(例如,计算校验和应该在某些应用程序中一直进行),但这些情况是规则的例外。

在您使用电子邮件的示例中,回调方法存在一些缺点:

邮件程序界面和列表模型因不同原因(Single Responsibility Principle)而发生变化。

例如,您希望使用特殊队列发送电子邮件。与队列通信的接口不应以任何方式影响列表模型的构建方式。

您的申请一直不需要通过电子邮件发送。

电子邮件只是与外界互动的手段之一。并非所有业务逻辑都需要与外部世界联系在一起。其中一个例子,如apneadiving提到的是导入。另一个例子是控制台界面(您希望在使用rails控制台时发送电子邮件吗?)

测试很困难。

这更多是1和2的结果,但随着时间的推移,测试after钩子越来越困难。在测试Listing模型时需要模拟邮件程序,这使得测试不清楚,并且每当有变化时都难以维护。