简体   繁体   English

Rails 3.控制器中的继承回调方法

[英]Rails 3. Inheritance callback method in the controller

I have 2 controllers 我有2个控制器

OauthController and Admin::OauthController. OauthController和Admin :: OauthController。 When Admin::OauthController inherited from OauthController. 当Admin :: OauthController从OauthController继承时。

In OauthController implemented method "callback", which is public. 在OauthController中实现的方法“回调”是公开的。

Admin::OauthController looks like: Admin :: OauthController看起来像:

class Admin::OauthController < OauthController
end

Then if I go to the link "/admin/facebook_oauth/callback" get error 然后,如果我转到链接“ / admin / facebook_oauth / callback”,则会出现错误

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. 但是,如果我在Admin :: OauthController中添加带有call super的'callback'方法,那么所有方法都可以使用。

class Admin::OauthController < OauthController    
  def callback
    super
  end
end

This behavior appears after migration to Rails 3. Other methods are inherited OauthController without problems. 迁移到Rails 3后,将出现此行为。其他方法继承自OauthController,没有问题。

Error "raise ActionNotFound" raised if we do not have the desired action in the list of "action_methods" 如果我们在“ action_methods”列表中没有所需的动作,则会引发错误“ raise ActionNotFound”

AbstractController::Base#internal_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" 不要进入最终列表“ 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM