Internationalization 如何使用收件人';在Rails 3中发送电子邮件;什么地方?

Internationalization 如何使用收件人';在Rails 3中发送电子邮件;什么地方?,internationalization,ruby-on-rails-3,actionmailer,Internationalization,Ruby On Rails 3,Actionmailer,如何使用收件人的区域设置在邮件发送程序中发送邮件。我有数据库中每个用户的首选区域设置。请注意,只要当前用户不是收件人,这与当前区域设置(I18n.locale)不同。因此,困难的是在不更改I18n.locale的情况下在不同的语言环境中使用邮件程序: def new_follower(user, follower) @follower = follower @user = user mail :to=>@user.email end 在邮件之前使用I18n.locale=@u

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

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

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

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

使用它,您可以执行以下操作:

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

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

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


上述插件的问题在于它们不能在所有情况下都工作,例如,执行User.human\u name或User.human\u attribute\u name(…)将无法正确翻译。以下是最简单且有保证的工作方法:

将其粘贴到某个位置(在初始值设定项或插件中):

模块I18nActionMailer def自带(基本) 基本类\u评估do 包括实例方法 别名\u方法\u链:创建!,:场所 结束 结束 模块实例方法 def使用_语言环境创建_!(方法名称,*参数) 原始语言环境=I18n.locale 开始 创建没有区域设置的区域!(方法名称,*参数) 确保 I18n.locale=原始语言环境 结束 结束 结束 结束 ActionMailer::Base.send(:include,I18nActionMailer) 然后在mailer类中,通过设置所需的区域设置来启动方法,例如:

def welcome(user) I18n.locale = user.locale # etc. end def欢迎(用户) I18n.locale=user.locale #等等。 结束
在目前最新版本的rails中,使用它就足够了 “I18n.locale=account.locale” 在控制器中,使用以下命名策略创建多个视图 welcome.html.erb, welcome.it.html.erb和e.g。
welcome.fr.html.erb

这个答案是一个肮脏的黑客,它忽略了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
classsystemmailer@user.email)}
结束
受保护的
使用_区域设置(区域设置和块)定义
原始语言环境=I18n.locale
I18n.locale=locale
返回值=收益率
I18n.locale=原始语言环境
返回值
结束
结束

自从版本3开始翻译主题和内容,并确保将区域设置重置回原始区域设置后,上述所有操作都不起作用。。。因此,我做了以下工作(所有mailer都从该类继承):

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
您可以使用i18n_subject方法,该方法对当前路径进行范围限定,以便对所有内容进行结构化:

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

我认为最好的方法是使用很棒的方法
I18n。使用_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
它将更改区域设置以发送电子邮件,并在阻止结束后立即更改回


来源:

此外,如果试图通过I18n.locale=whateverI更改区域设置,我会得到一个“SystemStackError:stack level to deep”错误;还有一个活动的Rails错误:谢谢!但你指的是哪个插件?:)哎呀,忘记链接了!:D现在它在那里,它是i18n_action_mailer插件。不幸的是,它没有满足我的目的,因为我对每个区域设置有不同的视图:welcome.es.erb、welcome.en.erb等。该插件只重载t和l方法。是的,如果我需要,我需要使用额外的部分来处理它们,只是说:=render:partial=>“template#{i18n.locale}”等等。,然后将视图命名为“welcome_es.erb”等,比您提到的方式更难看,但仍然只是增加了一行……如果您使用需要翻译的布局,则需要在每个mailer方法上添加“layout”email_35;{I18n.locale},这也有点难看,因此,一个更干净的解决方案肯定会受到欢迎。谢谢你的插件。但是,它仍然无法根据Rails 3下的区域设置选择适当的视图。我认为,
reset_locale
应该将I18n.locale设置为初始值,而不是默认值。其他一切似乎都好。谢谢你为我做的工作。您还可以在邮件程序中设置区域设置。当我尝试在rails 3.2.8上运行类`ActionMailer::Base'(NameError)时,此代码为类`ActionMailer::Base'(NameError)呈现以下错误“
alias_method”:undefined method
create!”。此解决方案是唯一对我有效的解决方案,尽管我尝试了本文中列出的大多数答案。谢谢@jimwormt这里有一个I18n.with_locale方法
mail(:subject => i18n_subject(:name => @user.name)
def new_follower(user, follower)
  @follower = follower
  @user = user
  I18n.with_locale(@user.profile.locale) do
    mail to: @user.email
  end
end