Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle urls in emails with apartment gem

I am using the apartment gem for multi-tenancy.

Everything works fine besides urls in my emails. So for each email which is sent from any requests and from background jobs are using the default_url_options for the host.

Any suggestions on how to handle the host switch in emails?

like image 615
Chilianu Bogdan Avatar asked Nov 23 '15 14:11

Chilianu Bogdan


2 Answers

A different idea for a monkey patch:

# app/models/action_dispatch_routing_subdomain_extension.rb

module ActionDispatch::Routing

  module RouteSetExtensions

    # This allows lambdas as subdomain parameter for `default_url_options`:
    #
    #    config.action_mailer.default_url_options = {
    #      host: 'example.com',
    #      protocol: 'https',
    #      subdomain: lambda { ... }
    #    }
    #
    def url_for(options, route_name = nil, url_strategy = ActionDispatch::Routing::RouteSet::UNKNOWN)

      if options[:subdomain].respond_to? :call
        options[:subdomain] = options[:subdomain].call
      end

      if Rails.application.config.action_mailer.default_url_options[:subdomain].respond_to? :call
        options[:subdomain] ||= Rails.application.config.action_mailer.default_url_options[:subdomain].call
      end

      super(options, route_name, url_strategy)

    end
  end

  class RouteSet
    prepend RouteSetExtensions
  end

end

Initializer:

# config/initializers/action_dispatch_routing_subdomain_extension.rb
require 'action_dispatch_routing_subdomain_extension'

Then, you can just use a lambda in the subdomain definition:

# config/environments/production.rb

Rails.application.configure do
  # ...

  config.action_mailer.default_url_options = {
    host: 'example.com',
    protocol: 'https',
    subdomain: lambda { Apartment::Tenant.current }
  }
end
like image 121
fiedl Avatar answered Oct 19 '22 13:10

fiedl


You can achieve this with a little monkey patch to allow you to set the default_url_options with a lambda. Add this to lib/dynamic_url_options and include it in your environments config:

module ActionDispatch::Routing
  class RouteSet

    alias_method :original_url_for, :url_for

    def url_for(options, route_name = nil, url_strategy = UNKNOWN)
      dynamic_options = Rails.application.config.respond_to?(:dynamic_url_options) ? Rails.application.config.dynamic_url_options.call : {}
      options = options.merge(default_url_options).merge(dynamic_options)

      original_url_for options, route_name, url_strategy
    end
  end
end

Then you can do something along the following lines in your environment config:

config.action_mailer.default_url_options = {
  host: 'yourdomain.com'
}

config.dynamic_url_options = lambda {{
  subdomain: Apartment::Tenant.current
}}
like image 1
Kent Mewhort Avatar answered Oct 19 '22 12:10

Kent Mewhort