Ruby / RoR: вызывать оригинальный метод через super ()? - PullRequest
12 голосов
/ 28 февраля 2011

В приложении RoR я хочу специализировать метод update_attributes () ActiveRecord в одной из моих моделей, извлекая некоторые атрибуты для специальной обработки и передавая остальные из них оригинальному методу 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 ()?

Ответы [ 3 ]

41 голосов
/ 01 марта 2011

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

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

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

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

16 голосов
/ 28 февраля 2011

Вы хотите:

super(attrs)

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

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

4 голосов
/ 28 февраля 2011

Это выглядит как лучшее использование для 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...