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

Пустая область с Ruby on Rails

Следующая проблема:
Мне нужно что-то вроде пустого пространства. Это означает, что этот объем является 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
4b9b3361

Ответ 1

То, что вы ищете, не существует. Вы могли бы реализовать что-то вроде этого путем monky-исправления метода find. Тем не менее, это было бы излишним, поэтому я рекомендую сохранить это, если это не критично.

Ответ 2

Rails 4 вводит область none.

Он должен использоваться в тех случаях, когда у вас есть метод, который возвращает отношение, но есть условие, в котором вы не хотите запрашивать базу данных.

Если вы хотите, чтобы область возвращала неизмененную область применения, используйте all:

Больше не будет вызов Model.all немедленно выполнить запрос и вернуть массив записей. В Rails 4 вызовы Model.all эквивалентны теперь устаревшим Model.scoped. Это означает, что больше отношений может быть привязано к Model.all, и результат будет лениво оценен.

Ответ 3

User.where('false')

возвращает ActiveRecord:: Relation с нулевыми элементами, то есть область с возможностью цепочки, которая не попадет в базу данных, пока вы не попытаетесь получить доступ к одному из ее элементов. Это похоже на решение PhilT с ('1 = 0'), но немного более элегантным.

Ответ 4

Извините User.scoped не то, что вы хотите. Как прокомментировал это, все возвращается. Должно было уделить больше внимания вопросу.

Я видел предлагаемый ранее where('1 = 0'), и Rails, вероятно, должен также кэшировать его.

Кроме того, where('1 = 0') не попадет в базу данных до тех пор, пока вы не выполните .all, .each или один из методов расчета.

Ответ 5

Мне нужно User.scoped({})

Ответ 6

Как насчет User.where(id: nil)?

Или User.where(_id: nil) для монгоида.

Ответ 7

Глядя на ваш пример кода, вы можете не знать об агрегированных запросах в SQL, которые отображаются как методы вычислений в Rails:

User.sum(:score) даст вам сумму всех оценок пользователей

Взгляните на Rails Guides для получения дополнительной информации:

http://guides.rubyonrails.org/active_record_querying.html#sum