送货方式视情况而定? Rails

Delivery method based on condition? Rails

Rails 4.1.4,我有很多class个Mailer,它们的投递方式都不一样。现在这给我带来了麻烦。

在开发和测试环境中,当我将 delivery_method 作为 :test 时,如果我使用下面的 class 执行和交付,则交付方法变为 :custom_method,即使尽管我在 rails 环境文件中提到了 config.delivery_method = :test

class CustomMailer < ActionMailer::Base

  default :delivery_method => :custom_method,
          from: "...",
          reply_to: '...'

  def emailer(emails)
    mail(to: emails, subject: 'test')
  end

end

在开发和测试环境中将 :custom_method 更改为 :test 的正确方法是什么?

我实施的一个可行的解决方案是:

class CustomMailer < ActionMailer::Base

  DELIVERY_METHOD = Rails.env == 'production' ? :custom_method : :test

  default :delivery_method => DELIVERY_METHOD,
          from: "...",
          reply_to: '...'

  def emailer(emails)
    mail(to: emails, subject: 'test')
  end

end

这对我有用,但我觉得这不是一个好方法,因为我必须写这行:

DELIVERY_METHOD = Rails.env == 'production' ? :custom_method : :test

在每个 Mailer class 中,这会导致冗余。如果能以某种通用的方式处理就太好了。

请注意,每个 Mailer class 都有 不同的 投递方式class。

如何创建一个 ApplicationMailer 并让所有其他邮件程序继承 ApplicationMailer?这是现在 Rails5 中的方法。下面的代码显示了一种在子邮件程序中定义传递方法并从 ApplicationMailer 继承选择逻辑的可能方法。

class ApplicationMailer < ActionMailer::Base
  SELECTOR = Hash.new { |h,k| h[k] = k }
  DELIVERY_METHOD = Rails.env.production? ? :custom_method : :test ##selection logic, use: env, env variables ...
end

class UserMailer < ApplicationMailer
  SELECTOR[:custom_method] = :sendmail  ##class-specific delivery method
  default delivery_method: SELECTOR[DELIVERY_METHOD]
  ##....
end

您采用的方法确实有效,但我认为在您的代码中查询 Rails.env 是一种反模式。

您可以通过设置 custom config attribute 来使用应用程序配置。这是一个例子:

# config/production.rb
Rails.application.configure do
  # by having this configured by an environment variable 
  # you can have different values in staging, 
  # develop, demo, etc.. They all use "production" env.
  config.x.mailer_livemode = ENV['MAILER_LIVEMODE']
end

# config/development.rb
Rails.application.configure do
  config.x.mailer_livemode = false
end

# config/test.rb
Rails.application.configure do
  config.x.mailer_livemode = false
end

# app/mailers/custom_mailer.rb
default delivery_method: Rails.application.config.x.mailer_livemode ? :custom_method : :test

灵活性优越。您可以让多个配置变量协同工作,直接在配置中设置 delivery_method,等等

最重要的是,对于与您的电子邮件发送方式有关的事情,您不会依赖无关紧要的事情(Rails.env)。