A partir de Rails 4, Model.scoped está ahora en desuso.


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

Pero, hay una diferencia enModel.scoped y Model.all, que es, scoped.scoped devuelve un ámbito, mientras que all.all se ejecuta la consulta.

On Rails 3:

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

On 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 /preocupaciones que devuelve scoped cuando hay un condicional para hacer algo o nada, así:

module AmongConcern
  extend ActiveSupport::Concern

  module ClassMethods
    def among(ids)
      return scoped if ids.blank?

      where(id: ids)
    end
  end
end

Si quieres cambiar esta scoped a all, tendría que enfrentar problemas de azar dependiendo de donde la among fue utilizada en el ámbito de la cadena. Por ejemplo, Model.where(some: value).among(ids) tendría que ejecutar la consulta en lugar de devolver un ámbito.

Lo que yo quiero es un idempotente método en ActiveRecord::Relation que simplemente devuelve un ámbito.

¿Qué debo hacer aquí?

  • Está seguro de que «all ejecuta la consulta» cosas no es sólo un artefacto de la consola? fuente, sugiere que debería funcionar bien.
  • Sí, estoy seguro. github.com/rails/activerecord-deprecated_finders/blob/v1.0.3/…
  • Pero usted no está recibiendo la advertencia, por lo que está recibiendo el all de scoping/named.rb, ¿verdad? Y el all de scoping/named.rb es, AFAIK, lo que Model.all usos.
  • Eh? github.com/rails/rails/blob/v4.0.0/activerecord/…
  • Hmm. Usted está recibiendo la advertencia. Suspiro, WTF gran pila de confusión sin sentido es Rieles hasta ahora. Es todavía la semana del tiburón ‘cuz estoy pensando que Rails4 ha saltado él.
  • lol sí. Sólo necesito algo mejor que donde(nil) para que.
  • Así que el problema es .all.all en lugar de sólo .all. Tal vez un vergonzoso is_a? ActiveRecord::Relation chequeo de hacer que el dolor desaparezca. Me siento sucio, creo que tengo que ir a lavar mi cerebro con cerveza ahora.
  • Llegó hasta el mismo problema, parece que es rieles de error
  • ¿Crear un tema para esto en rails’ bugtracker?
  • github.com/rails/rails/issues/12756

InformationsquelleAutor kenn | 2013-08-13

4 Comentarios

  1. 63

    Parece que where(nil) es un verdadero reemplazo de scoped, que trabaja tanto en los Carriles 3 y 4. 🙁

    • OMG de verdad? WTF.
    • El mismo mensaje de advertencia que dice utilizar load.
    • se dice que el uso de load SI desea con ganas de carga, y en cualquier caso se requiere de un parámetro (condición), así que por ahora where(nil) (o true o {} o 1) parece ser el mejor reemplazo de scoped
    • No funciona en mi caso: user.active_section.scoped.uniq(false) obras, user.active_section.all.uniq(false) o user.active_section.where(nil).uniq(false) no.
    • Cómo sobre rieles 5?
  2. 25

    On Rails 4.1 (beta 1), las siguientes obras:

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

    Así que parece que este problema ha sido resuelto, y en 4.1.0 Model.scoped ha sido eliminado por completo.

    • Genial, gracias por la actualización! Sin embargo, si estás en una joya de un mantenedor usted debe continuar el uso de where(nil) hasta 4.0.x es incompatible…
    • Este es un hilo muy antiguo pero estamos actualizando sólo ahora y debe mantener el apoyo de los Rails 3 y 4 también. Es razonable hacer algo a lo largo de las líneas de if ActiveRecord::VERSION::MAJOR == 3 then Model.scoped else Model.all end?
  3. 9

    Como se menciona en uno de los comentarios, all se supone que devuelve un ámbito de acuerdo a la documentación.

    Los documentos son correctos — lo devuelven una ActiveRecord::Relación, pero usted tiene que utilizar un semi-colon si usted quiere ver en la consola:

    pry(main)> u = User.all;
    
    pry(main)> u.class
    
    => ActiveRecord::Relation::ActiveRecord_Relation_User
    • Es irrelevante – trate de User.all.all; y se obtiene la misma advertencia. Por desgracia no va a ser fijos hasta Rails 4.x o incluso 5 Rieles. github.com/rails/rails/issues/12756
  4. 4

    Además de la utilización de where(nil) también puede llamar a clone si usted sabe que self es una Relación y obtener el mismo comportamiento de llamar scoped sin argumentos, sin el mismo mensaje de advertencia.

    EDITAR

    Ahora estoy usando este código como una gota en el reemplazo para scoped ya que no me gusta el uso de where(nil) en todas partes tengo que conseguir el ámbito 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é el AR autores no podría haber hecho algo similar, ya que, como el OP señala all y scoped hacer no se comportan de la misma.

    • Usted no puede llamar a clone en una clase del modelo. (por ejemplo,Model.clone) scoped trabajado tanto en el modelo de clases y relaciones.
    • Sí, por eso me dijo: «si usted sabe que auto es una Relación» más arriba.

Dejar respuesta

Please enter your comment!
Please enter your name here