app/models/customailer/mail_template.rb
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