似乎 alias_method 在 class << self 块内部的工作方式与在外部的工作方式不同。具体来说,当我将 alias_method 用于实例方法并随后覆盖该方法时,可以使用别名来访问原始方法。但是,我无法使用类方法来做到这一点。
这是我的用例:我正在覆盖从 ActiveRecord 基继承的 destroy 和 destroy_all 方法,因为当前编写的代码很容易在您打算删除连接记录时意外删除行。这种设计可能会随着一个更大的项目而改变,但现在这是我的解决方案,因为大多数情况下,没有人会想要从这个表中删除行。但是为了仍然允许出于善意的目的故意删除表中的行,我使用 alias_method 来保留原始destroy和destroy_all方法的句柄。使用别名可以访问原始的 :destroy (实例)方法,但不允许我访问原始的 :destroy_all (类)方法
class HoldReason < ActiveRecord::Base
class << self
alias_method :remove_hold_reasons_from_table, :destroy_all
def destroy_all
raise "Nope"
end
end
alias_method :remove_hold_reason, :destroy
def destroy
raise "Nope"
end
end
在这里,我们看到虽然此策略确实适用于允许成功删除单行的实例方法:
> HoldReason.find_by(title: "Management Review").remove_hold_reason
HoldReason Load (0.7ms) SELECT `hold_reasons`.* FROM `hold_reasons` WHERE `hold_reasons`.`title` = 'Management Review' LIMIT 1
(0.5ms) BEGIN
SQL (4.6ms) DELETE FROM `hold_reasons` WHERE `hold_reasons`.`id` = 23
(0.6ms) COMMIT
=> #<HoldReason id: 23, title: "Management Review", category: "Operations">
我无法访问原始的 :destroy_all 方法以在一个查询中删除多行;相反,即使我使用别名,我也会得到覆盖的方法:
> HoldReason.remove_hold_reasons_from_table
HoldReason Load (0.7ms) SELECT `hold_reasons`.* FROM `hold_reasons`
RuntimeError: Nope
发生了什么事,我似乎无法为类方法执行此操作,我该如何修复它(除了使用原始 SQL 查询进行删除)?