Si tengo un alcance con una lambda y requiere un argumento, dependiendo del valor del argumento, podría saber que no habrá coincidencias, pero aún quiero devolver una relación, no una matriz vacía:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
Lo que realmente quiero es un método "ninguno", lo opuesto a "todos", que devuelve una relación que aún puede encadenarse, pero da como resultado un cortocircuito en la consulta.
ruby-on-rails
activerecord
relation
dzajic
fuente
fuente
Respuestas:
Ahora hay un mecanismo "correcto" en Rails 4:
fuente
Model.scoped
hace lo que estás buscando en los rieles 3.Model.none
no funciona. Debe usar uno de sus nombres de modelo reales , por ejemplo,User.none
o lo que tenga.Una solución más portátil que no requiere una columna "id" y no supone que no habrá una fila con un id de 0:
Todavía estoy buscando una forma más "correcta".
fuente
scope :none, -> { where("false") }
Próximamente en Rails 4
En Rails 4, se devolverá un encadenable
ActiveRecord::NullRelation
de llamadas comoPost.none
.Ni él ni los métodos encadenados generarán consultas a la base de datos.
Según los comentarios:
Ver el código fuente .
fuente
Puede agregar un ámbito llamado "ninguno":
Eso le dará un ActiveRecord vacío :: Relación
También puede agregarlo a ActiveRecord :: Base en un inicializador (si lo desea):
Hay muchas maneras de obtener algo como esto, pero ciertamente no es lo mejor para mantener en una base de código. He utilizado el alcance: ninguno al refactorizar y encontrar que necesito garantizar un ActiveRecord :: Relation vacío por un corto tiempo.
fuente
where('1=2')
podría ser un poco más concisoModel.none
es como lo haría.Es una solución peligrosa porque su alcance podría estar encadenado.
Usuario.ninguno.primero
devolverá el primer usuario. Es más seguro usar
fuente
Creo que prefiero la forma en que esto se ve a las otras opciones:
Llevando a algo como esto:
fuente
where(false)
qué no haría el trabajo: deja el alcance sin cambios.limit(0)
se anulará si llama.first
o.last
más adelante en la cadena, ya que Rails se agregaráLIMIT 1
a esa consulta.none
relación que se menciona a continuación.Uso con alcance:
Pero también puede simplificar su código con:
Si desea un resultado vacío, use esto (elimine la condición if):
fuente
Es posible y eso es:
http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/none
Corrígeme si me equivoco.
fuente
También hay variantes, pero todas están solicitando a db
fuente
where(false)
owhere(nil)
simplemente se ignora.