ruby-on-rails relaciones - ¿Cómo devolver una relación vacía de ActiveRecord?




5 Answers

Ahora hay un mecanismo "correcto" en Rails 4:

>> Model.none 
=> #<ActiveRecord::Relation []>
en llaves

Si tengo un ámbito con un lambda y toma un argumento, dependiendo del valor del argumento, puedo 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 ser encadenada, pero que resulta en una consulta cortocircuitada.




Puedes agregar un alcance llamado "ninguno":

scope :none, where(:id => nil).where("id IS NOT ?", nil)

Eso te dará un ActiveRecord vacío :: Relación

También puede agregarlo a ActiveRecord :: Base en un inicializador (si lo desea):

class ActiveRecord::Base
 def self.none
   where(arel_table[:id].eq(nil).and(arel_table[:id].not_eq(nil)))
 end
end

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.




scope :none, limit(0)

Es una solución peligrosa porque su alcance podría estar encadenado.

Usuario.none.first

Volverá el primer usuario. Es más seguro de usar

scope :none, where('1 = 0')



Utilizar ámbito:

scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : scoped }

Pero, también puedes simplificar tu código con:

scope :for_users, lambda { |users| where(:user_id => users.map(&:id)) if users.any? }

Si desea un resultado vacío, use esto (elimine la condición if):

scope :for_users, lambda { |users| where(:user_id => users.map(&:id)) }






Related