2011-02-28 22 views
11

在RoR應用程序中,我想在我的一個模型中專門化ActiveRecord的update_attributes()方法,提取一些特殊處理的屬性並將其餘的部分傳遞給原始的update_attributes()方法。細節:Ruby/RoR:通過super()調用原始方法?

class Premise < ActiveRecord::Base 
    ... 
    def update_attributes(attrs) 
    attrs.each_pair do |key, val| 
     unless has_attribute?(key) 
     do_special_processing(key, val) 
     attrs.delete(key) 
     end 
    end 
    # use original update_attributes() to process non-special pairs 
    super.update_attributes(attrs) 
    end 
    ... 
end 

到super.update_attributes(attr)使用這個調用產生了一個錯誤:

undefined method `update_attributes' for true:TrueClass 

...這使我懷疑我真不明白,在Ruby中super關鍵字。我錯過了什麼?具體來說,我如何調用原始的update_attributes()方法?

回答

15

你想:

super(attrs) 

這將調用原始的方法,將ATTRS作爲參數傳遞給它。

就像現在一樣,您試圖對原始update_attributes返回的「true」值調用update_attributes。

+4

在這種情況下,'update_attributes(attrs)'和'super(attrs)'的參數是相同的。你可以簡單地調用'super',而不用括號。 – 2011-02-28 21:29:43

+0

@LBg啊,謝謝,好點。關於這個問題,我在答覆結束時也糾正了一下;我原本寫這個問題的代碼被稱爲update_attributes沒有參數,但這是不正確的。 – DSimon 2011-03-01 15:12:38

+0

賓果 - 謝謝。我作爲Java程序員的過去正在通過... – 2011-03-01 21:50:17

4

這看起來像alias_method_chain更好地利用:

def update_attributes_with_special(attrs) 
    attrs.each_pair do |key, val| 
    unless has_attribute?(key) 
     do_special_processing(key, val) 
     attrs.delete(key) 
    end 
    end 
    update_attributes_without_special(attrs) 
end 
alias_method_chain :update_attributes, :special 
+0

展現出來。這引出了下一個問題:你什麼時候子類化,什麼時候鏈接? – 2011-03-01 21:54:50

+0

@FearlessFool:繼承通常是Ruby中的一種代碼異味,沒有共享內部狀態/資源的引人注目的參數。使用alias_method鏈的好處是吃你的蛋糕,並擁有它。你得到一個修改了update_attributes()的類,並保留未修改的功能。 – Winfield 2011-03-01 23:29:15

35

在Ruby超是一種特殊情況下的括號做的事...

中的方法調用super不帶參數(括號也不)如果所有參數都傳遞給子類方法,則子類將在超類(或其祖先,如果超類未定義它)中調用相同的方法。所以,在這裏,你可以簡單地寫超級。

調用super()調用超(或祖先)方法而沒有任何參數(假設該方法接受沒有參數...)

與參數的任意組合調用super(...)調用超類方法,向它傳遞PARAMATERS

+0

男人這是非常有用的。如何顯式發送相同的接收參數,方法是'method(param,* otherargs)'? – unmultimedio 2017-01-07 03:47:39