Con Rails 4, Model.scoped está en desuso, pero Model.all no puede reemplazarlo

Starting Rails 4, Model.scoped ahora está en desuso.

DEPRECATION WARNING: Model.scoped is deprecated. Please use Model.all instead.

Sin embargo, existe una diferencia en Model.scoped y Model.all , es decir, scoped.scoped devuelve un ámbito, mientras que all.all ejecuta la consulta.

En Rails 3:

 > Model.scoped.scoped.is_a?(ActiveRecord::Relation) => true 

En Rails 4:

 > Model.all.all.is_a?(ActiveRecord::Relation) DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (eg `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (eg `Post.where(published: true).to_a`). => false 

Hay casos de uso en bibliotecas / inquietudes que devuelven un scoped cuando hay un condicional para hacer algo o nada, como ese:

 module AmongConcern extend ActiveSupport::Concern module ClassMethods def among(ids) return scoped if ids.blank? where(id: ids) end end end 

Si cambiara este scoped para all , se enfrentarían a problemas aleatorios dependiendo de dónde se utilizó el among en la cadena de scope. Por ejemplo, Model.where(some: value).among(ids) ejecutaría la consulta en lugar de devolver un ámbito.

Lo que quiero es un método idempotente en ActiveRecord::Relation que simplemente devuelva un scope.

¿Qué debería hacer aquí?

Parece que where(nil) es un reemplazo real del scoped , que funciona tanto en Rails 3 como en 4. 🙁

En Rails 4.1 (beta 1), funciona lo siguiente:

 Model.all.all.is_a?(ActiveRecord::Relation) => true 

Por lo tanto, parece que este problema se ha solucionado, y en 4.1.0 Model.scoped se ha eliminado por completo.

Como se menciona en uno de los comentarios, se supone que all debe devolver un scope de acuerdo con los documentos .

Los documentos son correctos, devuelve una relación ActiveRecord ::, pero debe usar un punto y coma si desea verla en la consola:

 pry(main)> u = User.all; pry(main)> u.class => ActiveRecord::Relation::ActiveRecord_Relation_User 

Además de usar where(nil) , también puede llamar a clone si sabe que self es una relación y obtiene el mismo comportamiento de llamada con scoped sin argumentos, sin la advertencia de desaprobación.

EDITAR

Ahora estoy usando este código como un reemplazo en el scoped porque no me gusta usar where(nil) todas partes necesito tener acceso al scope actual:

  # config/initializers/scoped.rb class ActiveRecord::Base # do things the modern way and silence Rails 4 deprecation warnings def self.scoped(options=nil) options ? where(nil).apply_finder_options(options, true) : where(nil) end end 

No veo por qué los autores de AR no podrían haber hecho algo similar, ya que, como OP lo señala all scoped no se comporta de la misma manera.