How can I send emails in Rails 3 using the recipient's locale?

后端 未结 7 1789
说谎
说谎 2021-02-03 23:44

How can I send mails in a mailer using the recipient\'s locale. I have the preferred locale for each user in the database. Notice this is different from the current locale (I18n

相关标签:
7条回答
  • 2021-02-03 23:52

    Here's an updated version that also supports the '.key' short-hand notation, so you don't have to spell out each key in its entirety.

    http://github.com/larspind/i18n_action_mailer

    0 讨论(0)
  • 2021-02-03 23:56

    None of the above is really working since the version 3 to translate both subject and content and be sure that the locale is reseted back to the original one... so I did the following (all mailer inherit from that class:

    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
    

    You just need to set the locale before you call the mail() method:

    set_locale @user.locale
    

    You can use the i18n_subject method which scope the current path so everything is structured:

    mail(:subject => i18n_subject(:name => @user.name)
    
    0 讨论(0)
  • 2021-02-03 23:58

    The problem with the mentioned plugins are that they don't work in all situations, for example doing User.human_name or User.human_attribute_name(...) will not translate correctly. The following is the easiest and guaranteed method to work:

    stick this somewhere (in initializers or a plugin):

      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)
    

    and then in your mailer class start your method by setting the desired locale, for example:

      def welcome(user)
        I18n.locale = user.locale
        # etc.
      end
    
    0 讨论(0)
  • 2021-02-04 00:01

    This simple plugin was developed for rails 2 but seems to work in rails 3 too.

    http://github.com/Bertg/i18n_action_mailer

    With it you can do the following:

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

    The subject and mail templates are then translated using the user's locale.

    0 讨论(0)
  • 2021-02-04 00:10

    I believe the best way to do this is with the great method I18n.with_locale, it allows you to temporarily change the I18n.locale inside a block, you can use it like this:

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

    And it'll change the locale just to send the email, immediately changing back after the block ends.

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

    0 讨论(0)
  • 2021-02-04 00:14

    This answer was a dirty hack that ignored I18n's with_locale method, which is in another answer. The original answer (which works but you shouldn't use it) is below.

    Quick and dirty:

    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
    
    0 讨论(0)
提交回复
热议问题