rails query left includes foreign active activerecord ruby-on-rails-4

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



rails find (4)

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 (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `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 alcance. 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 alcance.

¿Qué debería hacer aquí?


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 alcance 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.


Como se menciona en uno de los comentarios, se supone que all debe devolver un alcance 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


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.


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