简体   繁体   English

Ruby / RoR:通过super()调用原始方法?

[英]Ruby/RoR: calling original method via super()?

In a RoR app, I want to specialize ActiveRecord's update_attributes() method in one of my models, extracting some of the attributes for special handling and passing the rest of them to the original update_attributes() method. 在RoR应用程序中,我想在一个模型中对ActiveRecord的update_attributes()方法进行专门化处理,提取一些用于特殊处理的属性,然后将其余属性传递给原始的update_attributes()方法。 The details: 细节:

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

The call to super.update_attributes(attr) raises an error: 调用super.update_attributes(attr)会引发错误:

undefined method `update_attributes' for true:TrueClass

... which makes me suspect I really don't understand the super keyword in Ruby. ...这让我怀疑我真的不了解Ruby中的super关键字。 What am I missing? 我想念什么? Specifically, how do I call the original update_attributes() method? 具体来说,如何调用原始的update_attributes()方法?

In Ruby super is a special case where parenthesis do matter... 在Ruby中,超级是括号很重要的特殊情况...

Calling super without parameter (nor parenthesis) in a method of a subclass calls the same method in the super-class (or its ancestors if the superclass does not define it) with all the parameter passed to the subclass method. 在子类的方法中调用不带参数的超类(或不带括号)会调用super类中的相同方法(如果超类未定义其父类,则调用其祖先),并将所有参数传递给子类方法。 So, here, you could have written simply super. 因此,在这里,您可能只写了super。

Calling super() calls the superclass (or ancestors) method without any parameter (assuming this method accept no parameters...) 调用super()调用超类(或祖先)方法而没有任何参数(假设此方法不接受任何参数...)

Calling super(...) with any combination of parameters calls the superclass method, passing it the paramaters 使用参数的任意组合调用super(...)调用超类方法,并将其传递给参数

You want: 你要:

super(attrs)

That will call the original method, passing attrs as an argument to it. 这将调用原始方法,并将attrs作为参数传递给它。

As it is now, you're trying to call update_attributes on the "true" value returned by the original update_attributes. 现在,您正在尝试对原始update_attributes返回的“ true”值调用update_attributes。

This looks like a better use for alias_method_chain: 这似乎是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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM