[英]ruby alias_method in class method
似乎alias_method在一個類<< self block中的工作方式不同於外部。 具體來說,當我對實例方法使用alias_method並隨后覆蓋該方法時,可以使用別名來訪問原始方法。 但是,我無法使用類方法執行此操作。
這是我的用例:我重寫了從ActiveRecord base繼承的destroy和destroy_all方法,因為當前編寫的代碼使得在刪除連接記錄時很容易意外刪除行。 這個設計可能會隨着一個更大的項目而改變,但是現在這是我的解決方案,因為在大多數情況下,沒有人會想要從這個表中刪除行。 但為了仍然允許故意刪除表中的行為善意,我使用alias_method以保留原始destroy和destroy_all方法的句柄。 使用別名正在訪問原始:destroy(實例)方法,但不允許我訪問原始:desotry_all(class)方法
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查詢進行刪除之外)?
答案是我沒有得到新的:destroy_all方法; 我正確地得到了舊的:destroy_all方法,這稱為:在引擎蓋下銷毀。 當然,通過調用:destroy,它得到了new:destroy方法,它引發了錯誤。 所以我似乎只是得到了新的類方法,因為新的類方法和新的實例方法引發了完全相同的錯誤。
如果我稍微修改一下,這會更清楚:
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.