В rails как я могу делегировать метод класса?

class Task < ActiveRecord::Base
  attr_accessible :due_date, :text

  def self.this_week
    where(:due_date => Date.today.beginning_of_week..Date.today.end_of_week)
  end
end

class Important < ActiveRecord::Base
  attr_accessible :email

  has_one :task, :as => :taskable, :dependent => :destroy

  delegate this_week, :to => :task
end

Пока этот делегат работает не так, как ожидалось, когда я пытаюсь Important.this_week. Я получаю сообщение о том, что для класса не существует метода this_week, определенного для класса...

Любые идеи? Могу ли я даже делегировать метод класса, подобный этому? У меня может быть другой класс или два расширения Task таким образом, поэтому мне любопытно, как это работает таким образом, чтобы не дублировать кучу кода для каждого класса реализации.

Спасибо

Ответ 1

Вы поднимаете расширение расширение ActiveSupport делегирования. Помощник delegate определяет метод экземпляра для текущего класса, чтобы экземпляры его делегирования вызывали некоторую переменную в этом экземпляре.

Если вы хотите делегировать на уровне класса, вам нужно открыть класс singleton и настроить там делегирование:

class Important < ActiveRecord::Base
  attr_accessible :email

  has_one :task, :as => :taskable, :dependent => :destroy

  class << self
    delegate :this_week, :to => :task
  end
end

Но это предполагает, что Important.task является ссылкой на класс Task (а это не так)

Вместо того, чтобы полагаться на помощника делегирования, который просто затруднит вашу жизнь, я бы предложил здесь явное проксирование:

class Important < ActiveRecord::Base
  attr_accessible :email

  has_one :task, :as => :taskable, :dependent => :destroy

  class << self
    def this_week(*args, &block)
      Task.this_week(*args, &block)
    end
  end
end

Ответ 2

Передайте метод методу класса, учитывая наследование:

delegate :this_week, :to => :class

Вы можете делегировать определенный класс (см. также ответ Исаака Бетеша):

delegate :this_week, :to => :Task

Документы доступны здесь: http://api.rubyonrails.org/classes/Module.html#method-i-delegate

Ответ 3

Вы можете делегировать метод константе - это просто чувствительный к регистру. Кроме того, имя метода должно быть передано delegate в качестве символа.

class Important < ActiveRecord::Base
  delegate :this_week, :to => :Task
  # Note ':this_week' instead of 'this_week'
  # Note 'Task' instead of 'task'
end