Подтвердить что ты не робот

Rails: возможно ли определить именованный объект в модуле?

Скажем, что есть 3 модели: A, B и C. Каждая из этих моделей имеет атрибут x.

Возможно ли определить именованный объект в модуле и включить этот модуль в A, B и C?

Я попытался сделать это и получил сообщение об ошибке, в котором говорилось, что scope не распознается...

4b9b3361

Ответ 1

Да, это

module Foo
  def self.included(base)
    base.class_eval do
      scope :your_scope, lambda {}
    end
  end
end

Ответ 2

В Rails 3.1 синтаксис немного упрощается благодаря ActiveSupport:: Concern:

Теперь вы можете сделать

require 'active_support/concern'

module M
  extend ActiveSupport::Concern

  included do
    scope :disabled, where(:disabled => true)
  end

  module ClassMethods
   ...
  end
end

ActiveSupport:: Концерн также просматривает зависимости от включенного модуля, вот документация

[обновление, обращение к комментарию aceofbassgreg]

Rails 3.1 и более поздние версии ActiveSupport:: Concern позволяют включать включенные методы экземпляра модуля, так что нет необходимости создавать модуль InstanceMethods внутри входящего модуля. Также в Rails 3.1 больше не требуется включать M:: InstanceMethods и расширять M:: ClassMethods. Таким образом, у нас может быть более простой код:

require 'active_support/concern'
module M
  extend ActiveSupport::Concern
  # foo will be an instance method when M is "include"'d in another class
  def foo
    "bar"
  end

  module ClassMethods
    # the baz method will be included as a class method on any class that "include"s M
    def baz
      "qux"
    end
  end

end

class Test
  # this is all that is required! It a beautiful thing!
  include M
end

Test.new.foo # ->"bar"
Test.baz # -> "qux"

Ответ 3

Что касается Rails 4.x, вы можете использовать gem scopes_rails

Он может сгенерировать файл scopes и включить его в вашу модель.

Кроме того, он может автоматически генерировать области видимости для состояний state_machines.