Цепочки ответственности и проблемы alias_method в Ruby - PullRequest
3 голосов
/ 30 июня 2010

Я пытаюсь реализовать шаблон цепочки ответственности в Ruby и ActiveRecord для полиморфного объекта.У меня есть несколько проблем.

  • Иногда я получаю сообщение об ошибке, что метод не определен, когда я пытаюсь его alias_method, я думаю, это потому, что класс не загружен или что-то так, яexplicity сделать посылку, чтобы получить метод
  • Я получаю кучу бесконечных цепочек, где функция с псевдонимом (original_method) вызывает метод, который вызывает original_method.Мне интересно, если это так, потому что когда вы создаете псевдоним метода, который уже был перезаписан, вы, по сути, делаете «original_method» копией метода с псевдонимом.функция типа «цепочка» возвращает подкласс Setting со всеми определенными методами, но любопытно, почему было так много проблем с alias_method прямо в классе.

Вот пример:

class Hospital
  has_one :setting, :as => :settable
  belongs_to :administrative_area

  def next_link
    adminstrative_area
  end

  def usable_setting
    setting ? setting : next_link.usable_setting
  end
end

Тогда у меня есть объект настройки:

class Setting < ActiveRecord::Base

belongs_to :settable, :polymorphic => true

def chained
  %w(api_key active_days).each do |method|

    # this is here because otherwise the method isn't defined,
    # it's almost as while it's going up, the metaclass doesn't have the columns
    # until it loads, probably will be fixed if we cache classes
    self.send method.to_sym

    (class << self; self; end).class_eval do

      define_method method do |*args|
        alias_method "original_#{method}", method
        my_setting = send("original_#{method}")
        if my_setting.nil? or my_setting.empty?
          settable.next_link.usable_setting.chained.send(method)
        else
          return my_setting
        end
      end
    end
  end
  self
end
end

1 Ответ

1 голос
/ 08 июля 2010

Вы, кажется, слишком усложняете. Кажется, вы пытаетесь увидеть, существуют ли api_key и active_days, и если нет, то получите его откуда-то еще.

Вот правильный способ сделать это, предполагая, что api_key и active_days - это столбцы в вашей таблице:

class Setting < ActiveRecord::Base

  belongs_to :settable, :polymorphic => true

  def api_key
    super || settable.next_link.usable_setting.api_key
  end

  def active_days
    super || settable.next_link.usable_setting.active_days
  end
end

Вы можете немного изменить его, чтобы сохранить ясность и удалить дубликаты.

class Setting < ActiveRecord::Base

  belongs_to :settable, :polymorphic => true

  def api_key
    super || next_usable_setting.api_key
  end

  def active_days
    super || next_usable_setting.active_days
  end

  private
  def next_usable_setting
    settable.next_link.usable_setting
  end
end

Так что в этом случае обратите внимание - если у вас есть api_key / active_days, он будет возвращен. В противном случае, он будет извлекать usable_setting из next_link. Если у этого есть api_key / active_days, он будет возвращен, в противном случае он получит usable_setting из next_link. И т.д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...