ruby alias_method in class method



似乎alias_method在类<<自我阻止中的工作方式与外部的工作方式不同。具体来说,当我对实例方法使用 alias_method 并随后重写该方法时,别名可用于访问原始方法。但是,我无法使用类方法执行此操作。

这是我的用例:我正在覆盖从 ActiveRecord 基继承的销毁和destroy_all方法,因为当前编写的代码使得在要删除联接记录时很容易意外删除行。该设计可能会随着更大的项目而改变,但现在这是我的解决方案,因为在大多数情况下,没有人愿意从此表中删除行。但是为了仍然允许有意删除表中的行,我正在使用alias_method来保留原始销毁和destroy_all方法的句柄。使用别名可以访问原始的 :d estroy(实例)方法,但不允许我访问原始的 :d esotry_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">

我无法访问原始的 :d estroy_all 方法来删除一个查询中的多行;相反,即使我使用别名,我也得到了被覆盖的方法:

> HoldReason.remove_hold_reasons_from_table
  HoldReason Load (0.7ms)  SELECT `hold_reasons`.* FROM `hold_reasons`
RuntimeError: Nope
发生了什么,我

似乎无法为类方法执行此操作,我该如何解决它(除了使用原始SQL查询进行删除)?

答案是我没有得到新的 :d estroy_all 方法;我正确地得到了旧的:d estroy_all方法,这在引擎盖下称为:d estroy。当然,通过调用:d estroy,它得到了新的:d estroy方法,这引发了错误。所以看起来我只是在获得新的类方法,因为新的类方法和新的实例方法引发了完全相同的错误。

如果我稍微修改一下,这一点会更清楚:

class HoldReason < ActiveRecord::Base
  class << self
    alias_method :remove_hold_reasons_from_table, :destroy_all
    def destroy_all
      raise "Don't destroy_all (multiple: class method)"
    end
  end
  alias_method :remove_hold_reason, :destroy
  def destroy
    raise "Don't destroy (single: instance method)"
  end
end

结果在

> HoldReason.remove_hold_reasons_from_table
RuntimeError: Don't destroy (single: instance method)

相关内容

  • 没有找到相关文章

最新更新