1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Include routes helpers only for inherited classes in ActionMailer

This commit is contained in:
Piotr Sarnacki 2010-08-02 16:04:39 +02:00
parent befa77fc18
commit 32baa27892
5 changed files with 67 additions and 27 deletions

View file

@ -5,6 +5,7 @@ require 'active_support/core_ext/array/wrap'
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.
@ -346,6 +347,7 @@ module ActionMailer #:nodoc:
helper ActionMailer::MailHelper
include ActionMailer::OldApi
include ActionMailer::HideActions
delegate :register_observer, :to => Mail
delegate :register_interceptor, :to => Mail
@ -361,6 +363,11 @@ module ActionMailer #:nodoc:
}.freeze
class << self
def inherited(klass)
klass.with_hiding_actions do
super(klass)
end
end
def mailer_name
@mailer_name ||= name.underscore
@ -725,27 +732,8 @@ module ActionMailer #: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

View file

@ -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

View file

@ -19,9 +19,8 @@ module ActionMailer
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

View file

@ -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

View file

@ -410,6 +410,7 @@ module RailtiesTest
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)