Ответ 1
То, что вы ищете, не существует. Вы могли бы реализовать что-то вроде этого путем monky-исправления метода find
. Тем не менее, это было бы излишним, поэтому я рекомендую сохранить это, если это не критично.
Следующая проблема:
Мне нужно что-то вроде пустого пространства. Это означает, что этот объем является emtpy, но отвечает на все методы, на которые обычно реагирует область.
В настоящее время я использую небольшой грязный хак. Я просто поставлю "1 = 0" в качестве условий. Я нахожу это очень уродливым, так как оно попадает в базу данных. Простое возвращение пустого массива не будет работать, так как результат должен отвечать на методы с областью.
Есть ли лучшее существующее решение для этого или мне нужно будет сам это сделать?
Возможно, какой-то примерный код может помочь объяснить, что мне нужно:
class User < ActiveRecord::Base
named_scope :admins, :conditions => {:admin => true }
named_scope :none_dirty, :conditions => "1=0" # this scope is always empty
def none_broken
[]
end
def self.sum_score # okay, a bit simple, but a method like this should work!
total = 0
self.all.each do |user|
total += user.score
end
return total
end
end
User.admin.sum_score # the score i want to know
User.none_drity.sum_score # works, but hits the db
User.none_broken.sum_score # ...error, since it doesn't respond to sum_score
То, что вы ищете, не существует. Вы могли бы реализовать что-то вроде этого путем monky-исправления метода find
. Тем не менее, это было бы излишним, поэтому я рекомендую сохранить это, если это не критично.
Rails 4 вводит область none
.
Он должен использоваться в тех случаях, когда у вас есть метод, который возвращает отношение, но есть условие, в котором вы не хотите запрашивать базу данных.
Если вы хотите, чтобы область возвращала неизмененную область применения, используйте all
:
Больше не будет вызов Model.all
немедленно выполнить запрос и вернуть массив записей. В Rails 4 вызовы Model.all
эквивалентны теперь устаревшим Model.scoped
. Это означает, что больше отношений может быть привязано к Model.all
, и результат будет лениво оценен.
User.where('false')
возвращает ActiveRecord:: Relation с нулевыми элементами, то есть область с возможностью цепочки, которая не попадет в базу данных, пока вы не попытаетесь получить доступ к одному из ее элементов. Это похоже на решение PhilT с ('1 = 0'), но немного более элегантным.
Извините User.scoped
не то, что вы хотите. Как прокомментировал это, все возвращается. Должно было уделить больше внимания вопросу.
Я видел предлагаемый ранее where('1 = 0')
, и Rails, вероятно, должен также кэшировать его.
Кроме того, where('1 = 0')
не попадет в базу данных до тех пор, пока вы не выполните .all
, .each
или один из методов расчета.
Мне нужно User.scoped({})
Как насчет User.where(id: nil)
?
Или User.where(_id: nil)
для монгоида.
Глядя на ваш пример кода, вы можете не знать об агрегированных запросах в SQL, которые отображаются как методы вычислений в Rails:
User.sum(:score)
даст вам сумму всех оценок пользователей
Взгляните на Rails Guides для получения дополнительной информации:
http://guides.rubyonrails.org/active_record_querying.html#sum