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_scope
condiciones? 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_scope
menos que realmente tenga que hacerlo. Probablemente estará mejor con ámbitos con nombre. Dicho esto, puede usarwith_exclusive_scope
para anular el alcance predeterminado si es necesario.Echa un vistazo a esta pregunta para más detalles.
fuente
default_scope
puede parecer una buena idea, pero probablemente causará múltiples dolores de cabeza durante la vida útil de su aplicación.with_exclusive_scope
fue eliminado en rieles 3default_scope
es una herramienta excelente y hay situaciones en las que podríadefault_scope
hacerlo de otra manera, pero es lo correcto. Por ejemplo, cuando tiene unProduct
modelo que tiene unainactive
bandera,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 llamaunscoped
al 1% de casos restantes, que probablemente sea un panel de administración.En Rails 3:
fuente
def self.random; unscoped.order('rand()'); end
unscoped elimina ALL sql antes, no solo lo que se enumera en default_scope. Aunque técnicamente es una respuesta correcta, tenga cuidado de usarunstopped
unscoped
cuando 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 elreorder
mé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.1
puede usarActiveRecord::QueryMethods#unscope
para combatir el alcance predeterminado:Es actualmente posible
unscope
cosas como::where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having
.Pero aún así , evite usar
default_scope
si puede . Es por tu propio bien.fuente
Puede anular un alcance predeterminado utilizando el
with_exclusive_scope
método Entonces:with_exclusive_scope
documentació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_scope
de 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_sql
con la consulta completa. Por ejemplo: Model.find_by_sql ("SELECT * FROM modelos WHERE id = 123")fuente