Reload action_methods in AbstractController after defining new method.

Signed-off-by: José Valim <jose.valim@gmail.com>
This commit is contained in:
Piotr Sarnacki 2010-08-04 18:58:18 +02:00 committed by José Valim
parent 462666b737
commit 84f0a0bc30
4 changed files with 42 additions and 1 deletions

@ -507,6 +507,18 @@ def self.delivering_email(mail)
assert_equal("Thanks for signing up this afternoon", mail.subject)
end
test "action methods should be refreshed after defining new method" do
class FooMailer < ActionMailer::Base
# this triggers action_methods
self.respond_to?(:foo)
def notify
end
end
assert_equal ["notify"], FooMailer.action_methods
end
protected
# Execute the block setting the given values and restoring old values after

@ -72,6 +72,13 @@ def action_methods
end
end
# action_methods are cached and there is sometimes need to refresh
# them. clear_action_methods! allows you to do that, so next time
# you run action_methods, they will be recalculated
def clear_action_methods!
@action_methods = nil
end
# Returns the full controller name, underscored, without the ending Controller.
# For instance, MyApp::MyPostsController would return "my_app/my_posts" for
# controller_name.
@ -81,6 +88,11 @@ def action_methods
def controller_path
@controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous?
end
def method_added(name)
super
clear_action_methods!
end
end
abstract!

@ -250,5 +250,19 @@ def assert_dispatch(klass, body = "success", action = :index)
end
end
class Me6 < AbstractController::Base
self.action_methods
def index
end
end
class TestActionMethodsReloading < ActiveSupport::TestCase
test "action_methods should be reloaded after defining a new method" do
assert_equal ["index"], Me6.action_methods
end
end
end
end

@ -419,7 +419,10 @@ def __create_keyed_callback(name, kind, object, &blk) #:nodoc:
@_keyed_callbacks ||= {}
@_keyed_callbacks[name] ||= begin
str = send("_#{kind}_callbacks").compile(name, object)
class_eval "def #{name}() #{str} end", __FILE__, __LINE__
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{name}() #{str} end
protected :#{name}
RUBY_EVAL
true
end
end