2012-04-23 12 views
12

Tengo dos tablas: abogado y teléfono. El teléfono está separado en código de área y número. Un abogado tiene muchos teléfonos. Deseo generar una consulta que busque abogados que tengan un teléfono que coincida con un teléfono de una lista de teléfonos.Múltiples o condiciones en ActiveRecord

Si tuviera sólo un teléfono que podía buscar así:

Lawyer.join(:phones).where(:area_code => area_code, :number => number) 

El problema es que tengo una lista con más de un código de área. Así que realmente quiero hacer algo como esto:

lawyers = [] 
phones.each { |phone| lawyers += Lawyer.join(:phones).where(:area_code => phone[:area_code], :number => phone[:number]) } 

Sin embargo, no quiero hacer muchas consultas. ¿No se puede hacer en una sola declaración de consulta?

Editar: Así es como haría algo similar usando SQL solo (suponiendo que la lista de números fuera [{: area_code => '555',: number => '1234564'}, {: area_code => ' 533' ,: número => '12345678'}])

select * from phones where (area_code, number) in (('555', '1234564'), ('533', '12345678')) 

Si alguien puede conseguir que traducido en ActiveRecord, eso sería genial.

Respuesta

13

Si pasa una matriz de códigos_rea, AR generará una condición IN. Lo que podría utilizar la búsqueda y uso original matrices lugar:

donde Area_Codes es un conjunto de Area_Codes y números de una matriz de números:

Lawyer.join(:phones).where(:area_code => area_codes, :number => numbers) 

o:

Lawyer.join(:phones).where("phones.area_code IN (?) AND phones.number IN (?)", area_codes, numbers) 

debe ceder:

SELECT * from lawyers JOIN phones ON phones.lawyer_id = lawyers.id WHERE phones.area_code IN (...) AND phones.number IN (...) 
+0

Pensé sobre eso, pero no funciona exactamente como quiero. El problema es que dos códigos de área podrían tener el mismo número de teléfono. Digamos que estamos buscando dos teléfonos: [{: area_code => 555,: number => 5555555}, {: area_code => 444,: number => 12345678}]. Si utilizo su enfoque, entonces un abogado que vive en el código de área 444 con el número 5555555 coincidiría. No quiero eso. –

+0

Ah, veo tu problema ahora. Personalmente, "desnormalizaré" los datos en una columna para que sea más amigable para las búsquedas. De lo contrario, supongo que podrías construir una condición where haciendo un bucle de cada código y número, pero esa solución me gusta mucho menos. – miked

+1

Es fácil hacer esto en SQL: seleccione * desde teléfonos donde (area_code, number) in (('555', '5555555'), ('444', '12345678')) Así que realmente no hay razón para desnormalizar los datos. Todo lo que necesito hacer es cómo traducir eso en ActiveRecord. –

0
Lawyer.join(:phones).where(
    "(phones.area_code, phones.number) IN (('555', '5555555'), ('444', '12345678'))" 
) 
Cuestiones relacionadas