Если у меня есть ActiveRecord :: Base модель с областью действия по умолчанию:
class Foo < ActiveRecord::Base
default_scope :conditions => ["bar = ?",bar]
end
Есть ли способ сделать Foo.find
без использования default_scope
условий? Другими словами, можете ли вы переопределить область по умолчанию?
Я бы подумал , что с помощью « по умолчанию» во имя будет предположить , что это было переопределение, в противном случае это будет называться что - то вроде global_scope
, не так ли?
ruby-on-rails
Gareth
источник
источник
Ответы:
Краткий ответ: не используйте,
default_scope
если вам действительно не нужно. Вам, вероятно, будет лучше с именованными областями. С учетом сказанного, вы можете использоватьwith_exclusive_scope
для переопределения области по умолчанию, если вам нужно.Посмотрите на этот вопрос для более подробной информации.
источник
default_scope
может показаться хорошей идеей, но, вероятно, вызовет множество головных болей в течение всего срока службы вашего приложения.with_exclusive_scope
был снят в рельсах 3default_scope
это отличный инструмент, и есть ситуации, когда вы могли бы по-другому, ноdefault_scope
это как раз то, что нужно делать. Например, если у вас естьProduct
модель, у которой естьinactive
флаг,default_scope { where inactive: false }
лучше всего сделать настройку , так как в 99% случаев вы не захотите отображать неактивный продукт. Затем вы просто вызываетеunscoped
оставшиеся 1% случаев, которые, вероятно, являются панелью администратора.В Rails 3:
источник
def self.random; unscoped.order('rand()'); end
unscoped удаляет ВСЕ sql перед ним, а не только то, что указано в default_scope. Хотя технически правильный ответ, будьте осторожны, используяunstopped
unscoped
тогда, когда оно может напрямую следовать модели, например,Foo.unscoped.blah()
это нормально, но никогдаFoo.blah().unscoped
.Если все, что вам нужно, это изменить порядок, определенный в
default_scope
, вы можете использоватьreorder
метод .запускает следующий SQL:
источник
scope :without_default_order, -> { reorder("") }
и вы можете сделать что-то вроде:Foo.without_default_order.order("created_at ASC")
В некоторых ситуациях она читается лучше (возможно, не в этой точной ситуации, но у меня была такая).Так как
4.1
вы можете использоватьActiveRecord::QueryMethods#unscope
для борьбы с областью по умолчанию:В настоящее время можно делать
unscope
вещи вроде::where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having
.Но все же, пожалуйста, избегайте использования,
default_scope
если можете . Это для вашего же блага.источник
Вы можете переопределить область по умолчанию, используя
with_exclusive_scope
метод. Так:with_exclusive_scope
документацияисточник
Rails 3 default_scope не переопределяется, как это было в Rails 2.
например
В моем приложении, использующем PostgreSQL, упорядочение по умолчанию в области WINS. Я удаляю все свои default_scopes и кодирую это явно везде.
Касаемо Rails3!
источник
Bar.foos.reorder(:created_at => :asc)
С Rails 3+ вы можете использовать комбинацию unscoped и merge:
источник
User.unscoped.where(email: "foo@example.com")
На Rails 5.1+ (а может и раньше, но я проверял, что он работает на 5.1) можно отменить выборку конкретного столбца, что imho является идеальным решением для удаления
default_scope
способа, который можно использовать внутри именованной области видимости. В случае ОПdefault_scope
,Или
Оба приведут к SQL-запросу, который не применяет исходную область, но применяет любые другие условия, объединенные в arel.
источник
Ну, вы всегда можете использовать старые фавориты
find_by_sql
с полным запросом. Например: Model.find_by_sql («ВЫБРАТЬ * ИЗ МОДЕЛЕЙ, ГДЕ id = 123»)источник