2011-04-01 7 views
12

Tengo un ámbito de Rails 3 que excluye una matriz de identificadores.Raíles con alcance que no hace nada para los valores NOT IN

¿Cuál es la mejor manera de escribir el osciloscopio para que no haga nada cuando la matriz está vacía y todavía puede encadenarse? En este momento tengo presente, que funciona, pero parece un poco mal:

scope :excluding_ids, 
     lambda {|ids| ids.empty? ? relation : where('id not in (?)', ids) } 

Si no tengo el "ids.empty relación:??" bits, cuando IDS es vacía el SQL generado es

... ID not in (NULL) ... 

que siempre devolverá nada. Así que algo como:

Model.excluding_ids([]).where('id > 0') 

devuelve ningún resultado.

Respuesta

19

Si la matriz ids está vacía, entonces no devuelve nada.

scope :excluding_ids, lambda { |ids| 
    where(['id NOT IN (?)', ids]) if ids.any? 
} 

La consulta se ejecuta sin limitaciones adicionales a la consulta si no hay ids.

+0

de qué. –

+0

Gracias por la edición. (eliminado mi comentario anterior que tenía un error ya que no puedo editarlo ahora) – tee

+0

¡Ah, mucho mejor! Le doy a tu respuesta un unicornio. –

0

¿Qué tal lo siguiente? (Todavía comprueba si hay una matriz vacía, así que si eso es lo que estamos tratando de evitar que no es mucho de una mejora :)

scope :excluding_ids, 
    lambda {|ids| (ids.empty? && relation) || where('id not in (?)', ids) } 
3

Aquí hay una ligera variación en la respuesta de Douglas, usando la sintaxis Lambda stabby de ruby ​​1.9 y sin los corchetes en el método where.

scope :excluding_ids, ->(ids) {where("id NOT IN (?)", ids) if ids.any?} 
7

En Rails 4 se puede utilizar:

scope :excluding_ids, ->(ids) { where.not(id: ids) } 
+1

¿No quiere decir "... -> (ids) {where.not (id: ids)}"? Ver: http://edgeguides.rubyonrails.org/active_record_querying.html#passing-in-arguments –

+1

Sí, ¡respuesta actualizada! – GuiGS

Cuestiones relacionadas