2011-02-28 63 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