Skip to content

Commit

Permalink
Include routes helpers only for inherited classes in ActionMailer
Browse files Browse the repository at this point in the history
  • Loading branch information
drogus committed Sep 3, 2010
1 parent befa77f commit 32baa27
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 27 deletions.
30 changes: 9 additions & 21 deletions actionmailer/lib/action_mailer/base.rb
Expand Up @@ -5,6 +5,7 @@
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/proc'
require 'action_mailer/log_subscriber'
require 'action_mailer/hide_actions'

module ActionMailer #:nodoc:
# Action Mailer allows you to send email from your application using a mailer model and views.
Expand Down Expand Up @@ -346,6 +347,7 @@ class Base < AbstractController::Base

helper ActionMailer::MailHelper
include ActionMailer::OldApi
include ActionMailer::HideActions

delegate :register_observer, :to => Mail
delegate :register_interceptor, :to => Mail
Expand All @@ -361,6 +363,11 @@ class Base < AbstractController::Base
}.freeze

class << self
def inherited(klass)
klass.with_hiding_actions do
super(klass)
end
end

def mailer_name
@mailer_name ||= name.underscore
Expand Down Expand Up @@ -725,27 +732,8 @@ def insert_part(container, response, charset) #:nodoc:
container.add_part(part)
end

module DeprecatedUrlOptions
def default_url_options
deprecated_url_options
end

def default_url_options=(val)
deprecated_url_options
end

def deprecated_url_options
raise "You can no longer call ActionMailer::Base.default_url_options " \
"directly. You need to set config.action_mailer.default_url_options. " \
"If you are using ActionMailer standalone, you need to include the " \
"routing url_helpers directly."
end
end

# This module will complain if the user tries to set default_url_options
# directly instead of through the config object. In Action Mailer's Railtie,
# we include the router's url_helpers, which will override this module.
extend DeprecatedUrlOptions
class_attribute :default_url_options
self.default_url_options = {}

ActiveSupport.run_load_hooks(:action_mailer, self)
end
Expand Down
46 changes: 46 additions & 0 deletions actionmailer/lib/action_mailer/hide_actions.rb
@@ -0,0 +1,46 @@
require 'active_support/core_ext/class/attribute'

module ActionMailer
# ActionController::HideActions adds the ability to prevent public methods on a controller
# to be called as actions.
module HideActions
extend ActiveSupport::Concern

included do
class_attribute :hidden_actions
self.hidden_actions = Set.new.freeze
end

private

module ClassMethods
# Sets all of the actions passed in as hidden actions.
#
# ==== Parameters
# *args<#to_s>:: A list of actions
def hide_action(*args)
self.hidden_actions = hidden_actions.dup.merge(args.map(&:to_s)).freeze
end

# Run block and add all the new action_methods to hidden_actions.
# This is used in inherited method.
def with_hiding_actions
yield
clear_action_methods!
hide_action(*action_methods)
clear_action_methods!
end

def clear_action_methods!
@action_methods = nil
end

# Overrides AbstractController::Base#action_methods to remove any methods
# that are listed as hidden methods.
def action_methods
@action_methods ||= super.reject { |name| hidden_actions.include?(name) }
end
end
end
end

3 changes: 1 addition & 2 deletions actionmailer/lib/action_mailer/railtie.rb
Expand Up @@ -19,9 +19,8 @@ class Railtie < Rails::Railtie
options.stylesheets_dir ||= paths.public.stylesheets.to_a.first

ActiveSupport.on_load(:action_mailer) do
include app.routes.url_helpers
extend ::ActionMailer::Railties::RoutesHelpers.with(app.routes)
include app.routes.mounted_helpers(:app)
extend ::ActionMailer::Railties::RoutesHelpers
options.each { |k,v| send("#{k}=", v) }
end
end
Expand Down
14 changes: 10 additions & 4 deletions actionmailer/lib/action_mailer/railties/routes_helpers.rb
@@ -1,10 +1,16 @@
module ActionMailer
module Railties
module RoutesHelpers
def inherited(klass)
super(klass)
if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) }
klass.send(:include, namespace._railtie.routes.url_helpers)
def self.with(routes)
Module.new do
define_method(:inherited) do |klass|
super(klass)
if namespace = klass.parents.detect {|m| m.respond_to?(:_railtie) }
klass.send(:include, namespace._railtie.routes.url_helpers)
else
klass.send(:include, routes.url_helpers)
end
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions railties/test/railties/engine_test.rb
Expand Up @@ -410,6 +410,7 @@ class MyMailer < ActionMailer::Base

assert_equal Bukkits._railtie, Bukkits::Engine
assert ::Bukkits::MyMailer.method_defined?(:foo_path)
assert !::Bukkits::MyMailer.method_defined?(:bar_path)

env = Rack::MockRequest.env_for("/bukkits/from_app")
response = AppTemplate::Application.call(env)
Expand Down

0 comments on commit 32baa27

Please sign in to comment.