В rails как я могу делегировать метод класса? - программирование
Подтвердить что ты не робот

В 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 таким образом, поэтому мне любопытно, как это работает таким образом, чтобы не дублировать кучу кода для каждого класса реализации.

Спасибо

4b9b3361

Ответ 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