2012-02-21 16 views
13

Actualmente estoy escribiendo un método de búsqueda para mis aplicaciones de rieles, y por el momento funciona bien. Tengo el siguiente en mi game.rb:Buscar columnas múltiples - Rails

def self.search(search) 
    if search 
    find(:all, :conditions => ['game_name LIKE ? OR genre LIKE ? OR console LIKE ?', "%#{search}%", "#{search}", "#{search}"]) 
    else 
    find(:all) 
    end 
end 

Ahora que busca bien, pero mi problema es que si hay un registro en GAME_NAME que tiene la palabra 'PlayStation' en ella, se termina la búsqueda allí . Solo devuelve ese registro, en lugar de todos los juegos que tienen 'playstation' almacenada en la consola. Ahora entiendo que esto es porque tengo 'O' en mis condiciones, pero no sé una alternativa. 'AND' requiere que todas las condiciones coincidan o ninguna regresa. ¿Cuál es una alternativa que puedo usar para AND y OR? La ayuda sería muy apreciada.

Si hay una solución que tiene cuadros de búsqueda y entradas separadas, entonces estaría bien, no necesariamente necesito que la búsqueda lo encuentre todo basado en un formulario de búsqueda.

+0

puede ser una solución para usted es utilizar una joya para lo que quiere como https://github.com/ernie/meta_where – Awea

Respuesta

25

Si entiendo su pregunta correctamente, su SQL se ve bien para mí por lo que está tratando de hacer. Una cláusula OR devolverá todos los registros que coincidan en la columna 1, la columna 2 o la columna 3. No se detiene en el primer partido. Veo un problema con sus parámetros porque el primero está usando LIKE con% pero en los segundos dos no lo está, tal vez de ahí viene su problema.

¿Debería ser este su hallazgo (% en la segunda y tercera búsqueda)?

find(:all, :conditions => ['game_name LIKE ? OR genre LIKE ? OR console LIKE ?', "%#{search}%", "%#{search}%", "%#{search}%"]) 

o mejor utilización versión seca (anterior no funcionará para Rails 4.2 y versiones posteriores):

Item.where('game_name LIKE :search OR genre LIKE :search OR console LIKE :search', search: "%#{search}%") 
+1

Muchas gracias Jeff, puse el% en torno a la segunda y tercera búsqueda y funcionó bien, ni siquiera notó que faltaba. Saludos por toda la ayuda. – user1222136

+1

@items = Item.where ('game_name LIKE: buscar O género LIKE: buscar OR console LIKE: buscar', buscar: "% # {search}%") order (: nombre) – sunil

16

¿Qué pasa si usted tiene 15 columnas de buscar entonces usted va a repetir clave 15 veces. En lugar de repetir la tecla 15 veces en la consulta, puede escribir de esta manera:

key = "%#{search}%" 

@items = Item.where('game_name LIKE :search OR genre LIKE :search OR console LIKE :search', search: key).order(:name) 

Le dará el mismo resultado.

Gracias

4

creo que esto es un poco de una solución más limpia. Esto le permite agregar/eliminar columnas más fácilmente.

key = "%#{search}%" 
columns = %w{game_name genre console} 
@items = Item.where(
    columns 
    .map {|c| "#{c} like :search" } 
    .join(' OR '), 
    search: key 
) 
+0

Mismas respuestas pero esta definitivamente dice mejor. Sin embargo, el rendimiento tendría éxito, ¿no? En todas las respuestas se compara una clave con varias columnas, mientras más columnas tenga que mirar, más tiempo tomará. ¿No hay una mejor manera? – Breno

+0

@Breno - La única otra forma en que puedo pensar es concatenar todos los campos y luego buscar ese nuevo campo. fields =: name,: address_1,: address_2 Item.where ("concat_ws ('', # {fields.join (',')}) LIKE?", "% # {Key}%") –

Cuestiones relacionadas