最好将一个简单的函数作为类方法或模块附加?

时间:2013-08-22 20:06:07

标签: ruby-on-rails ruby module class-method

我有一个简单的功能,可以防止在本地测试时将电子邮件发送给客户:

def safe_emails emails
  if Rails.env == 'production'
    emails
  else
    emails.select{|e| ['staff@example.com', 'staff2@example.com'].include?(e) }
  end
end

我想在邮件之间分享这个功能。我可以看到两个选项,模块或类方法。

选项1:模块

class ReportMailer < ActionMailer::Base
  include SafeEmailer

  def daily emails
    mail_to: safe_emails(emails)
  end
end

选项2:类方法

class ReportMailer < ActionMailer::Base
  def daily emails
    mail_to: SafeEmailer.safe_emails(emails)
  end
end

由于全局范围,类方法是根据某些方法禁止的,包括具有一种方法的模块似乎并不具有吸引力。猴子修补ActionMailer在那里抛出方法似乎也可能导致麻烦(当Rails 4.3引入safe_emails方法或其他什么时)。

3 个答案:

答案 0 :(得分:1)

即使它是一个简单的功能模块,我也会使用模块选项。保持最终可以被模块中的多个类使用的泛型函数比在类中定义它更有意义。

如果您关心Rails 4.3,那么您可以简单地将include MySafeEmailModule替换为Rails 4.3中包含此函数的内容,而不是找到并替换对ReportMailer.daily_emails的所有调用。

答案 1 :(得分:1)

两者都没有 - 在您的情况下,您需要一个策略对象来决定谁收到有关Rails.env的电子邮件。我将这个逻辑保留在ReportMailer之外。

我会选择类似的东西:

UserMailer.welcome_email(@user).deliver if SafeEmailer.new(@user.email).safe?

答案 2 :(得分:1)

这可能是最简单的方法。

在非生产环境中设置以下配置。(config / environments / .rb)

config.action_mailer.delivery_method = :smtp (default), :sendmail, :test, or :file

看一下letter opener gem。您可以将delivery_method设置为letter_opener并在浏览器中打开电子邮件,而不是实际在非生产环境中发送它们。