Si tengo un modelo ActiveRecord :: Base con un alcance predeterminado:
class Foo < ActiveRecord::Base
default_scope :conditions => ["bar = ?",bar]
end
¿Hay alguna forma de hacerlo Foo.find sin usar las default_scopecondiciones? En otras palabras, ¿puede anular un alcance predeterminado?
Pensé que usar 'default' en el nombre sugeriría que era invalidable, de lo contrario se llamaría algo así global_scope, ¿verdad?
ruby-on-rails
Gareth
fuente
fuente

Respuestas:
Respuesta corta: no lo use a
default_scopemenos que realmente tenga que hacerlo. Probablemente estará mejor con ámbitos con nombre. Dicho esto, puede usarwith_exclusive_scopepara anular el alcance predeterminado si es necesario.Echa un vistazo a esta pregunta para más detalles.
fuente
default_scopepuede parecer una buena idea, pero probablemente causará múltiples dolores de cabeza durante la vida útil de su aplicación.with_exclusive_scopefue eliminado en rieles 3default_scopees una herramienta excelente y hay situaciones en las que podríadefault_scopehacerlo de otra manera, pero es lo correcto. Por ejemplo, cuando tiene unProductmodelo que tiene unainactivebandera,default_scope { where inactive: false }lo mejor es configurar un a, ya que en 99% o casos no querrá mostrar un producto inactivo. Luego solo llamaunscopedal 1% de casos restantes, que probablemente sea un panel de administración.En Rails 3:
fuente
def self.random; unscoped.order('rand()'); endunscoped elimina ALL sql antes, no solo lo que se enumera en default_scope. Aunque técnicamente es una respuesta correcta, tenga cuidado de usarunstoppedunscopedcuando puede seguir directamente un modelo, por ejemplo,Foo.unscoped.blah()está bien pero nuncaFoo.blah().unscoped.Si todo lo que necesita es cambiar el orden definido en
default_scope, puede usar elreordermétodo .ejecuta el siguiente SQL:
fuente
scope :without_default_order, -> { reorder("") }y puede hacer cosas comoFoo.without_default_order.order("created_at ASC")En algunas situaciones, se lee mejor (tal vez no sea esta situación exacta, pero tuve una).Como
4.1puede usarActiveRecord::QueryMethods#unscopepara combatir el alcance predeterminado:Es actualmente posible
unscopecosas como::where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having.Pero aún así , evite usar
default_scopesi puede . Es por tu propio bien.fuente
Puede anular un alcance predeterminado utilizando el
with_exclusive_scopemétodo Entonces:with_exclusive_scopedocumentaciónfuente
Rails 3 default_scope no parece anularse como lo hizo en Rails 2.
p.ej
En mi aplicación, usando PostgreSQL, el orden en el alcance predeterminado WINS. Estoy eliminando todos mis default_scopes y codificándolo explícitamente en todas partes.
Pitfall Rails3!
fuente
Bar.foos.reorder(:created_at => :asc)Con Rails 3+ puede usar una combinación de sin ámbito y fusión:
fuente
User.unscoped.where(email: "[email protected]")En Rails 5.1+ (y tal vez antes, pero he probado que funciona en 5.1), es posible quitar el alcance de una columna específica, lo que, en mi opinión, es la solución ideal para eliminar una
default_scopede una manera que se puede usar dentro de un alcance con nombre. En el caso de los POdefault_scope,O
Ambos darán como resultado una consulta sql que no aplica el alcance original, pero sí aplica cualquier otra condición que se combine en el arel.
fuente
Bueno, siempre puedes usar el favorito de antaño
find_by_sqlcon la consulta completa. Por ejemplo: Model.find_by_sql ("SELECT * FROM modelos WHERE id = 123")fuente