tutorial software rails ejemplos descargar curso caracteristicas ruby-on-rails

ruby on rails - software - Anulando un valor predeterminado de Rails



ruby on rails tutorial (8)

Bueno, siempre puedes usar el favorito de siempre find_by_sql con la consulta completa. Por ejemplo: Model.find_by_sql ("SELECT * FROM models WHERE id = 123")

Si tengo un modelo ActiveRecord :: Base con un alcance predeterminado:

class Foo < ActiveRecord::Base default_scope :conditions => ["bar = ?",bar] end

¿Hay alguna forma de hacer un Foo.find sin usar las condiciones de default_scope ? En otras palabras, ¿puede anular un alcance predeterminado?

Hubiera pensado que usar ''predeterminado'' en el nombre sugeriría que era invalidable, de lo contrario se llamaría algo así como global_scope , ¿verdad?


Con Rails 3+ puedes usar una combinación de no combinado y fusionar:

# model User has a default scope query = User.where(email: "[email protected]") # get rid of default scope and then merge the conditions query = query.unscoped.merge(query)


Desde 4.1 , puede usar ActiveRecord::QueryMethods#unscope para combatir el alcance predeterminado:

class User < ActiveRecord::Base default_scope { where tester: false } scope :testers, -> { unscope(:where).where tester: true } scope :with_testers, -> { unscope(:where).where tester: [true, false] } # ... end

Actualmente es posible unscope como:: :where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having unscope de unscope :where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having .

Pero aún así , evite el uso de default_scope si puede . Es por tu propio bien.


En Rails 3:

foos = Foo.unscoped.where(:baz => baz)


Puede anular un alcance predeterminado utilizando el método with_exclusive_scope . Asi que:

foos = Foo.with_exclusive_scope { :conditions => ["baz = ?", baz] }


Rails 3 default_scope no parece anulado como lo hizo en Rails 2.

p.ej

class Foo < ActiveRecord::Base belongs_to :bar default_scope :order=>"created_at desc" end class Bar < ActiveRecord::Base has_many :foos end > Bar.foos SELECT * from Foo where bar_id = 2 order by "created_at desc"; > Bar.unscoped.foos SELECT * from Foo; (WRONG! removes the "has" relationship) > Bar.foos( :order=>"created_at asc" ) # trying to override ordering SELECT * from Foo where bar_id = 2 order by "created_at desc, created_at asc"

En mi aplicación, usando PostgreSQL, el orden en el alcance predeterminado WINS. Estoy eliminando todos mis métodos predeterminados y codificándolo explícitamente en todas partes.

Pitfall Rails3!


Respuesta corta: no uses default_scope menos que realmente tengas que hacerlo. Probablemente será mejor con ámbitos con nombre. Dicho esto, puede usar with_exclusive_scope para anular el alcance predeterminado si es necesario.

Eche un vistazo a esta pregunta para más detalles.


Si todo lo que necesita es cambiar el orden definido en default_scope , puede usar el método de reorder .

class Foo < ActiveRecord::Base default_scope order(''created_at desc'') end Foo.reorder(''created_at asc'')

ejecuta el siguiente SQL:

SELECT * FROM "foos" ORDER BY created_at asc