Skip to content

Commit

Permalink
Reload action_methods in AbstractController after defining new method.
Browse files Browse the repository at this point in the history
Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information
drogus authored and josevalim committed Aug 4, 2010
1 parent 8736527 commit 4da32ba
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
12 changes: 12 additions & 0 deletions actionmailer/test/base_test.rb
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions actionpack/lib/abstract_controller/base.rb
Expand Up @@ -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.
Expand All @@ -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!
Expand Down
14 changes: 14 additions & 0 deletions actionpack/test/abstract/abstract_controller_test.rb
Expand Up @@ -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
5 changes: 4 additions & 1 deletion activesupport/lib/active_support/callbacks.rb
Expand Up @@ -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
Expand Down

0 comments on commit 4da32ba

Please sign in to comment.