在Redmine插件中通过alias_method_chain包装类方法
-
21-09-2019 - |
题
我不确定这个问题是 Rails 的普遍问题还是 Redmine 特有的问题。
有一个 User 类,它有一个类方法 try_to_login。我编写了一个包含 method_alias_chain 的模块来包装该方法并提供附加功能。如果我进入控制台并调用 try_to_login ,效果很好。我的包装器将被执行,一切都很好。但是,当我在服务器上运行它时,仅调用普通方法。包装纸从未被碰过。我向普通方法添加了一个记录器命令,以确保它确实被调用。
这是代码的简化版本:
require_dependency 'principal'
require_dependency 'user'
require 'login_attempt_count'
module UserLoginAttemptLimiterPatch
def self.included(base)
base.extend ClassMethods
base.class_eval do
class << self
alias_method_chain :try_to_login, :attempt_limit
end
end
end
module ClassMethods
def try_to_login_with_attempt_limit(login, password)
user = try_to_login_without_attempt_limit login, password
#stuff here gets called via console but not via browser
user
end
def authentication_failed(login)
#important code here
end
end
end
User.send(:include, UserLoginAttemptLimiterPatch)
此外,加载插件时需要此模块。
解决方案
您如何需要该模块?如果您在开发模式下运行,则可以在第一个请求后重新加载 User 类,这将清除您的补丁和 alias_method_chain。
您可以通过在调度程序(每次重新加载代码时运行)内进行修补来解决这个问题:
require 'dispatcher'
Dispatcher.to_prepare do
Issue.send(:include, MyMooPatch)
end
参考: http://theadmin.org/articles/2009/04/13/how-to-modify-core-redmine-classes-from-a-plugin/
不隶属于 StackOverflow