Если у меня есть область видимости с лямбдой, и она принимает аргумент, в зависимости от значения аргумента, я могу знать, что совпадений не будет, но я все же хочу вернуть отношение, а не пустой массив:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
Что я действительно хочу, так это метод «none», противоположный «all», который возвращает отношение, которое все еще может быть связано, но приводит к короткому замыканию запроса.
Ответы:
В Rails 4 теперь есть «правильный» механизм:
источник
Model.scoped
делает то, что вы ищете в рельсах 3.Model.none
не работает. Вам нужно использовать одно из ваших реальных названий моделей, напримерUser.none
или what-have-you.Более переносимое решение, которое не требует столбца «id» и не предполагает, что не будет строки с идентификатором 0:
Я все еще ищу более «правильный» путь.
источник
scope :none, -> { where("false") }
Прибытие в Rails 4
В Rails 4 цепочка
ActiveRecord::NullRelation
будет возвращена из вызовов вродеPost.none
.Ни он, ни цепные методы не будут генерировать запросы к базе данных.
По комментариям:
Смотрите исходный код .
источник
Вы можете добавить область под названием "none":
Это даст вам пустой ActiveRecord :: Relation
Вы также можете добавить его в ActiveRecord :: Base в инициализаторе (если хотите):
Множество способов получить что-то подобное, но, конечно, не лучшее, что нужно держать в кодовой базе. Я использовал область действия: ни один при рефакторинге и обнаружил, что мне нужно в течение короткого времени гарантировать пустой ActiveRecord :: Relation.
источник
where('1=2')
может быть немного более краткимModel.none
как вы это сделаете.Это опасное решение, потому что ваш прицел может быть прикован цепью.
User.none.first
вернет первого пользователя. Безопаснее в использовании
источник
Я думаю, что предпочитаю, как это выглядит, другим вариантам:
В результате чего-то вроде этого:
источник
where(false)
не сделал бы работу - это оставляет объем неизменным.limit(0)
это будет переопределено, если вы позвоните.first
или.last
позже в цепочке, так как Rails добавитLIMIT 1
этот запрос.none
отношение, как упомянуто ниже.Используйте область действия:
Но вы также можете упростить свой код с помощью:
Если вы хотите пустой результат, используйте это (удалите условие if):
источник
Это возможно и так вот:
http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/none
Поправьте меня если я ошибаюсь.
источник
Есть также варианты, но все они делают запрос к БД
источник
where(false)
илиwhere(nil)
просто игнорируется.