26

如何使用收件人的语言环境在邮件程序中发送邮件。我有数据库中每个用户的首选语言环境。请注意,这与当前语言环境 (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 可以解决邮件问题,但会改变线程其余部分的行为。

4

7 回答 7

44

我相信最好的方法是使用出色的方法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

于 2013-04-17T00:21:23.393 回答
6

这个答案是一个肮脏的黑客,忽略了 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
于 2011-07-15T11:56:57.270 回答
4

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

于 2011-06-06T23:22:47.103 回答
2

自第 3 版以来,上述所有方法都不能真正起作用,以翻译主题和内容,并确保将语言环境重置回原始语言……所以我做了以下事情(所有邮件程序都继承自该类:

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)
于 2011-09-22T10:30:52.740 回答
1

这是一个更新版本,它还支持“.key”简写符号,因此您不必完整地拼出每个键。

http://github.com/larspind/i18n_action_mailer

于 2010-09-20T19:03:06.820 回答
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

然后使用用户的语言环境翻译主题和邮件模板。

于 2010-08-30T13:53:00.523 回答
1

上述插件的问题在于它们并非在所有情况下都有效,例如执行 User.human_name 或 User.human_attribute_name(...) 将无法正确翻译。以下是最简单且有保证的工作方法:

把它贴在某个地方(在初始化程序或插件中):

  模块 I18nActionMailer
    def self.included(base)
      base.class_eval 做
        包括 InstanceMethods
        alias_method_chain :create!, :locale
      结尾
    结尾

    模块实例方法
      def create_with_locale!(method_name, *parameters)
        original_locale = I18n.locale
        开始
          create_without_locale!(method_name, *parameters)
        确保
          I18n.locale = original_locale
        结尾
      结尾
    结尾
  结尾

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

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

  def 欢迎(用户)
    I18n.locale = user.locale
    # ETC。
  结尾
于 2010-11-13T06:04:33.977 回答