RKushnir/customailer

View on GitHub
app/models/customailer/mail_template.rb

Summary

Maintainability
A
0 mins
Test Coverage
module Customailer
  class MailTemplate < ActiveRecord::Base
    validates :body, :path, presence: true

    validates :format, inclusion: Mime::SET.symbols.map(&:to_s)
    validates :locale, inclusion:
      {in: ->(_) { I18n.available_locales.map(&:to_s) }}
    validates :handler, inclusion:
      {in: ->(_) { ActionView::Template::Handlers.extensions.map(&:to_s) }}

    attr_accessible :body, :format, :handler, :locale, :partial, :path

    after_save :clear_resolver_cache
    after_destroy :clear_resolver_cache

    def clear_resolver_cache
      Resolver.instance.clear_cache
    end

    class Resolver < ActionView::Resolver
      require "singleton"
      include Singleton

      protected

      def find_templates(name, prefix, partial, details)
        conditions = {
          path: normalize_path(name, prefix),
          locale: normalize_array(details[:locale]).first,
          format: normalize_array(details[:formats]).first,
          handler: normalize_array(details[:handlers]),
          partial: partial || false
        }

        ::Customailer::MailTemplate.where(conditions).map do |record|
          initialize_template(record)
        end
      end

      # Normalize name and prefix, so the tuple ["index", "users"] becomes
      # "users/index" and the tuple ["template", nil] becomes "template".
      def normalize_path(name, prefix)
        prefix.present? ? "#{prefix}/#{name}" : name
      end

      # Normalize arrays by converting all symbols to strings.
      def normalize_array(array)
        array.map(&:to_s)
      end

      # Initialize an ActionView::Template object based on the record found.
      def initialize_template(record)
        source = record.body
        identifier = "MailTemplate - #{record.id} - #{record.path.inspect}"
        handler = ActionView::Template.registered_template_handler(record.handler)

        details = {
          format: Mime[record.format],
          updated_at: record.updated_at,
          virtual_path: virtual_path(record.path, record.partial)
        }

        ActionView::Template.new(source, identifier, handler, details)
      end

      # Make paths as "users/user" become "users/_user" for partials.
      def virtual_path(path, partial)
        return path unless partial
        if index = path.rindex("/")
          path.insert(index + 1, "_")
        else
          "_#{path}"
        end
      end
    end
  end
end