В 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