Общие области через модуль? - PullRequest
22 голосов
/ 06 сентября 2011

Я хочу высушить несколько моделей, переместив общие области в модуль, например:

module CommonScopes
  extend ActiveSupport::Concern

  module ClassMethods
    scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
  end
end

Я также хочу создать общие спецификации для тестирования модуля.К сожалению, когда я пытаюсь включить общую область в мою модель, я получаю:

undefined method `order' for CommonScopes::ClassMethods:Module

Есть идеи?Спасибо!

Ответы [ 3 ]

50 голосов
/ 26 ноября 2013

Как и в rails 4 синтаксис области действия , вы можете просто использовать лямбду, чтобы задержать выполнение кода (работает и в rails 3):

module CommonScopes
  extend ActiveSupport::Concern

  included do
    scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") }
  end
end
13 голосов
/ 06 сентября 2011

Вы можете использовать instance_eval

module CommonScopes
  extend ActiveSupport::Concern

  def self.included(klass)
    klass.instance_eval do
      scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
    end
  end
end
2 голосов
/ 06 сентября 2011

Поскольку ваш метод scope вызывается сразу, когда ваш модуль анализируется Ruby, и он недоступен из вашего CommonScopes модуля.

Но вы можете заменить вызов области действия методом класса:

module CommonScopes
  extend ActiveSupport::Concern

  module ClassMethods
    def ordered_for_display
      order("#{self.to_s.tableize}.rank asc")
     end
  end
end
...