I have 2 controllers
OauthController and Admin::OauthController. When Admin::OauthController inherited from OauthController.
In OauthController implemented method "callback", which is public.
Admin::OauthController looks like:
class Admin::OauthController < OauthController
end
Then if I go to the link "/admin/facebook_oauth/callback" get error
Unknown action
The action 'callback' could not be found for Admin::OauthController
But if I add 'callback' method with call super in Admin::OauthController all works.
class Admin::OauthController < OauthController
def callback
super
end
end
This behavior appears after migration to Rails 3. Other methods are inherited OauthController without problems.
Error "raise ActionNotFound" raised if we do not have the desired action in the list of "action_methods"
AbstractController::Base#internal_methods
# A list of method names that should be considered actions. This
# includes all public instance methods on a controller, less
# any internal methods (see #internal_methods), adding back in
# any methods that are internal, but still exist on the class
# itself. Finally, #hidden_actions are removed.
#
# ==== Returns
# * <tt>array</tt> - A list of all methods that should be considered actions.
def action_methods
@action_methods ||= begin
# All public instance methods of this class, including ancestors
methods = public_instance_methods(true).map { |m| m.to_s }.to_set -
# Except for public instance methods of Base and its ancestors
internal_methods.map { |m| m.to_s } +
# Be sure to include shadowed public instance methods of this class
public_instance_methods(false).map { |m| m.to_s } -
# And always exclude explicitly hidden actions
hidden_actions
# Clear out AS callback method pollution
methods.reject { |method| method =~ /_one_time_conditions/ }
end
end
Do not get into the final list "AbstractController::Base#internal_methods"
# A list of all internal methods for a controller. This finds the first
# abstract superclass of a controller, and gets a list of all public
# instance methods on that abstract class. Public instance methods of
# a controller would normally be considered action methods, so methods
# declared on abstract classes are being removed.
# (ActionController::Metal and ActionController::Base are defined as abstract)
def internal_methods
controller = self
controller = controller.superclass until controller.abstract?
controller.public_instance_methods(true)
end
And finally the most interesting:
>> ActionController::Base.instance_methods.include?('callback')
=> true
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.