Подтвердить что ты не робот

Ruby/RoR: вызов оригинального метода через super()?

В приложении RoR я хочу специализировать метод ActiveRecord update_attributes() в одной из моих моделей, извлекая некоторые атрибуты для специальной обработки и передавая остальную часть оригинальному методу update_attributes(). Подробности:

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

..., что заставляет меня подозревать, что я действительно не понимаю ключевое слово super в Ruby. Что мне не хватает? В частности, как мне вызвать исходный метод update_attributes()?

4b9b3361

Ответ 1

Вы хотите:

super(attrs)

Это вызовет исходный метод, передав attrs в качестве аргумента.

Как и сейчас, вы пытаетесь вызвать update_attributes на "истинное" значение, возвращаемое исходными update_attributes.

Ответ 2

В Ruby super - особый случай, когда скобки имеют значение...

Вызов super без параметра (или скобки) в методе подкласса вызывает тот же метод в суперклассе (или его предках, если суперкласс не определяет его) со всем параметром, переданным методу подкласса. Итак, здесь вы могли бы написать просто супер.

Вызов super() вызывает метод суперкласса (или предков) без какого-либо параметра (если этот метод не принимает никаких параметров...)

Вызов super(...) с любой комбинацией параметров вызывает метод суперкласса, передавая ему параметры

Ответ 3

Это похоже на лучшее использование для 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