Из справочника :
14 Области применения
[...]
Чтобы определить простую область действия, мы используем метод области действия внутри класса, передавая запрос, который мы хотели бы выполнить при вызове этой области:
class Article < ApplicationRecord
scope :published, -> { where(published: true) }
end
Это то же самое, что и определение метода класса, и то, что вы используете, зависит от личных предпочтений:
class Article < ApplicationRecord
def self.published
where(published: true)
end
end
Таким образом, scope
- это в основном просто причудливый способ создания метода класса, который должен иметь определенное поведение (т.е. возвращать отношение), а любой метод метода класса, который возвращает отношение, является областью действия. scope
раньше было чем-то особенным, но теперь это просто методы класса, и все методы класса копируются в отношения для поддержки цепочки.
Нет способа узнать, является ли метод Model.m
"реальной" областью действия, которая будет возвращать отношение или какой-либо метод случайного класса, не выполняя его и не проверяя, что он возвращает, или вручную проверяя его исходный код. scopes
метод, который вы ищете, ушел и никогда не вернется.
Вы можете попытаться занести в черный список любой метод класса, который, как вы знаете, плох так кроется ложь и безумие.
Единственный разумный вариант - вносить в белый список каждый классовый метод, который, как вы знаете, хорош и является тем, что вы хотите, чтобы пользователи могли вызывать. Затем вы должны отфильтровать массив scopes
в контроллере и внутри AssignableLearningObjectives::Collector
. Я бы проверил в обоих местах, потому что у вас могут быть разные критерии для того, что разрешено, в зависимости от того, какая информация доступна и по какому пути вы проходите через код; Скорее, СУХОЙ, но эффективность и надежность не дружат.
Вы можете применить белый список областей в конструкторе AssignableLearningObjectives::Collector
или в available_objectives
.
Если вы хотите что-то красивее, чем:
scopes.each{ |scope| objectives = objectives.send(scope) }
objectives
тогда вы можете использовать inject
:
def available_objectives
objectives = assignable_objectives....
scopes.inject(objectives) { |objectives, scope| objectives.send(scope) }
end