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

时间:2022-02-01 16:54:59

I have a simple function to prevent emails from being sent to customers when testing locally:

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

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

I want to share that function between mailers. I can see two options, a module or a class method.

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

Option 1: Module

选项1:模块

class ReportMailer < ActionMailer::Base
  include SafeEmailer

  def daily emails
    mail_to: safe_emails(emails)
  end
end

Option2: Class Method

选项2:类方法

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

The class method is a no-no according to some due to global scope, including a module with one method doesnt seem all that attractive. Monkey-patching ActionMailer to throw the method in there also seems like it could cause trouble (when Rails 4.3 introduces the safe_emails method or whatever).

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

3 个解决方案

#1


1  

I would go with module option even if it's a simple one function module. Keeping a generic function that can eventually be used by multiple classes in a module makes much more sense than defining it inside a class.

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

If Rails 4.3 is of your concern then you can simply replace your include MySafeEmailModule with whatever Rails 4.3 would include this function in, as compared to find and replace all calls to ReportMailer.daily_emails.

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

#2


1  

Neither – in your case, you'd need a policy object, that decides who receives email regarding the Rails.env. I'd keep that logic outside the ReportMailer.

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

I'd go with something like:

我会用以下的东西:

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

#3


1  

This is probably the easiest way.

这可能是最简单的方法。

Set the below configuration in your non production environments.(config/environments/.rb)

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

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

Have a look at letter opener gem. You could have the delivery_method set as letter_opener and have the emails open in browser instead of actually sending them in your non production environments.

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

#1


1  

I would go with module option even if it's a simple one function module. Keeping a generic function that can eventually be used by multiple classes in a module makes much more sense than defining it inside a class.

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

If Rails 4.3 is of your concern then you can simply replace your include MySafeEmailModule with whatever Rails 4.3 would include this function in, as compared to find and replace all calls to ReportMailer.daily_emails.

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

#2


1  

Neither – in your case, you'd need a policy object, that decides who receives email regarding the Rails.env. I'd keep that logic outside the ReportMailer.

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

I'd go with something like:

我会用以下的东西:

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

#3


1  

This is probably the easiest way.

这可能是最简单的方法。

Set the below configuration in your non production environments.(config/environments/.rb)

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

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

Have a look at letter opener gem. You could have the delivery_method set as letter_opener and have the emails open in browser instead of actually sending them in your non production environments.

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