rails query left joins inner includes active ruby-on-rails default-scope

ruby-on-rails - query - rails joins



¿Por qué el uso de los carriles default_scope a menudo recomienda no? (3)

Everywhere on Internet, las personas mencionan que usar los carriles default_scope es una mala idea, y los mejores resultados para default_scope en stackoverflow son sobre cómo sobrescribirlo. Esto se siente mal, y merece una pregunta explícita (creo).

Entonces, ¿por qué usar los rails default_scope es una mala idea?


Problema 1

Consideremos el ejemplo básico:

class Post < ActiveRecord::Base default_scope { where(published: true) } end

La motivación para publicar el valor predeterminado published: true , podría ser asegurarse de que tiene que ser explicto cuando quiera mostrar publicaciones (privadas) no publicadas. Hasta aquí todo bien.

2.1.1 :001 > Post.all Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = ''t''

Bueno, esto es más o menos lo que esperamos. Ahora intentemos:

2.1.1 :004 > Post.new => #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>

Y ahí tenemos el primer gran problema con el alcance predeterminado:

=> default_scope afectará la inicialización de su modelo

En una instancia recién creada de dicho modelo, se reflejará el default_scope . Así que, aunque es posible que haya querido asegurarse de no incluir las publicaciones no publicadas por casualidad, ahora está creando las publicadas por defecto.

Problema 2

Considera un ejemplo más elaborado:

class Post < ActiveRecord::Base default_scope { where(published: true) } belongs_to :user end class User < ActiveRecord::Base has_many :posts end

Permite obtener las primeras publicaciones de usuarios:

2.1.1 :001 > User.first.posts Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = ''t'' AND "posts"."user_id" = ? [["user_id", 1]]

Esto se ve como esperado (asegúrese de desplazarse completamente hacia la derecha para ver la parte sobre el ID_usuario).

Ahora queremos obtener la lista de todas las publicaciones, incluidas sin publicar, por ejemplo, para la vista del usuario conectado. Te darás cuenta de que tienes que ''sobrescribir'' o ''deshacer'' el efecto de default_scope . Después de un Google rápido, es probable que descubras acerca de sin unscoped . Vea lo que sucede a continuación:

2.1.1 :002 > User.first.posts.unscoped Post Load (0.2ms) SELECT "posts".* FROM "posts"

=> Sin Cobertura elimina TODOS los ámbitos que normalmente se aplican a su selección, incluidas (entre otras) asociaciones.

Hay varias formas de sobrescribir los diferentes efectos del default_scope . Hacerlo bien se complicated muy rápido y yo diría que no usar el default_scope en primer lugar, sería una opción más segura.


Solo encuentro que default_scope es útil solo para ordenar que algunos parámetros estén en orden asc o desc en todas las situaciones. De lo contrario, lo evito como la peste


default_scope se recomienda a menudo porque a veces se usa incorrectamente para limitar el conjunto de resultados. Un buen uso de default_scope es ordenar el conjunto de resultados.

Me mantendría alejado de usar where en default_scope y más bien crearía un alcance para eso.