如何使用收件人的区域设置在Rails 3中发送电子邮件?

时间:2010-08-22 01:46:56

标签: internationalization ruby-on-rails-3 actionmailer

如何使用收件人的区域设置在邮件程序中发送邮件。我有数据库中每个用户的首选语言环境。请注意,这与当前区域设置(I18n.locale)不同,只要当前用户不必是收件人即可。所以困难的是在不改变I18n.locale的情况下在不同的语言环境中使用邮件程序:

def new_follower(user, follower)
  @follower = follower
  @user = user
  mail :to=>@user.email
end

在mail:to => ...之前使用I18n.locale = @ user.profile.locale将解决邮件程序问题,但会改变线程其余部分的行为。

7 个答案:

答案 0 :(得分:40)

我认为最好的方法是使用优秀的方法I18n.with_locale,它允许您临时更改块内的I18n.locale,您可以像这样使用它:

def new_follower(user, follower)
  @follower = follower
  @user = user
  I18n.with_locale(@user.profile.locale) do
    mail to: @user.email
  end
end

它会改变区域设置只是为了发送电子邮件,在块结束后立即更改回来。

来源:http://www.rubydoc.info/docs/rails/2.3.8/I18n.with_locale

答案 1 :(得分:7)

这个答案是一个肮脏的黑客,忽略了I18n的with_locale方法,这是另一个答案。原始答案(有效,但你不应该使用它)如下。

又快又脏:

class SystemMailer < ActionMailer::Base
  def new_follower(user, follower)
    @follower = follower
    @user = user
    using_locale(@user.profile.locale){mail(:to=>@user.email)}
  end

  protected
  def using_locale(locale, &block)
    original_locale = I18n.locale
    I18n.locale = locale
    return_value = yield
    I18n.locale = original_locale
    return_value
  end
end

答案 2 :(得分:4)

在目前最新版本的rails中,它足以使用    “I18n.locale = account.locale” 在控制器中,使用以下命名策略创建多个视图    welcome.html.erb,    welcome.it.html.erb和例如    welcome.fr.html.erb

答案 3 :(得分:2)

以上这些都没有真正起作用,因为版本3要翻译主题和内容,并确保将语言环境重置为原始语言环境...所以我做了以下操作(所有邮件程序都继承自该类:< / p>

class ResourceMailer < ActionMailer::Base

  def mail(headers={}, &block)
    I18n.locale = mail_locale
    super
  ensure
    reset_locale
  end

  def i18n_subject(options = {})
    I18n.locale = mail_locale
    mailer_scope = self.class.mailer_name.gsub('/', '.')
    I18n.t(:subject, options.merge(:scope => [mailer_scope, action_name], :default => action_name.humanize))
  ensure
    reset_locale
  end  

  def set_locale(locale)
    @mail_locale = locale
  end

  protected

  def mail_locale
    @mail_locale || I18n.locale
  end

  def reset_locale
    I18n.locale = I18n.default_locale
  end

end

您只需在调用mail()方法之前设置语言环境:

set_locale @user.locale

您可以使用i18n_subject方法来调整当前路径的范围,以便所有内容都是结构化的:

mail(:subject => i18n_subject(:name => @user.name)

答案 4 :(得分:1)

这个简单的插件是为rails 2开发的,但似乎也适用于rails 3。

http://github.com/Bertg/i18n_action_mailer

有了它,您可以执行以下操作:

def new_follower(user, follower)
  @follower = follower
  @user = user
  set_locale user.locale
  mail :to => @user.email, :subject => t(:new_follower_subject)
end

然后使用用户的区域设置翻译主题和邮件模板。

答案 5 :(得分:1)

这是一个更新版本,也支持'.key'简写符号,因此您不必完整地拼出每个密钥。

http://github.com/larspind/i18n_action_mailer

答案 6 :(得分:1)

上述插件的问题在于它们在所有情况下都不起作用,例如,User.human_name或User.human_attribute_name(...)将无法正确转换。以下是最简单且有保证的工作方法:

坚持这个(在初始化器或插件中):

  module I18nActionMailer
    def self.included(base)
      base.class_eval do
        include InstanceMethods
        alias_method_chain :create!, :locale
      end
    end

    module InstanceMethods
      def create_with_locale!(method_name, *parameters)
        original_locale = I18n.locale
        begin
          create_without_locale!(method_name, *parameters)
        ensure
          I18n.locale = original_locale
        end
      end
    end
  end

  ActionMailer::Base.send(:include, I18nActionMailer)

然后在您的邮件程序类中,通过设置所需的区域设置来启动您的方法,例如:

  def welcome(user)
    I18n.locale = user.locale
    # etc.
  end