2012-02-21 2 views
13

Attualmente sto scrivendo un metodo di ricerca per le mie applicazioni rails e al momento funziona correttamente. Ho il seguente nel mio game.rb:Cerca più colonne - 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 

Ora che cerca bene, ma il mio problema è che se c'è un record in GAME_NAME che ha la parola 'playstation' in esso, si concluderà la ricerca ci . Restituisce solo quel record, piuttosto che tutti i giochi che hanno "playstation" archiviati nella console. Ora capisco questo perché ho "O" nelle mie condizioni, ma non conosco un'alternativa. 'AND' richiede che tutte le condizioni corrispondano o che non vengano restituite affatto. Qual è un'alternativa che posso usare per AND e OR? L'aiuto sarebbe molto apprezzato.

Se esiste una soluzione con caselle di ricerca e voci separate, non è necessario che la ricerca trovi tutto in base a un modulo di ricerca.

+0

può essere una soluzione per voi è quello di utilizzare un gioiello per ciò che si vuole come https://github.com/ernie/meta_where – Awea

risposta

25

Se ho capito bene la tua domanda, il tuo SQL mi sembra buono per quello che stai cercando di fare. Una clausola OR restituirà tutti i record che corrispondono in column1, column2 o column3. Non si ferma alla prima partita. Vedo un problema con i tuoi parametri in quanto il primo si sta usando LIKE con% ma nel secondo due non lo sei, forse è da lì che viene il tuo problema.

Questa dovrebbe essere la ricerca (% attorno alla seconda e alla terza ricerca)?

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

o meglio la versione DRY uso (di cui sopra non funziona per Rails 4.2+):

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

Grazie mille Jeff, ho messo il% intorno al secondo e terzo di ricerca e ha funzionato bene, non ha nemmeno notato che manca. Saluti per tutto l'aiuto. – user1222136

+1

@items = Item.where ('game_name LIKE: ricerca O genere LIKE: ricerca O console LIKE: search', cerca: "% # {search}%"). Order (: name) – sunil

16

Che cosa succede se si dispone di 15 colonne per cercare poi si ripeterà chiave 15 volte. Invece di ripetere la chiave 15 volte nella query, puoi scrivere in questo modo:

key = "%#{search}%" 

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

Ti darà lo stesso risultato.

Grazie

4

credo che questo sia un po 'di una soluzione più pulita. Questo ti permette di aggiungere/rimuovere colonne più facilmente.

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

Stesse risposte ma questo sicuramente si legge meglio. La performance sarebbe un successo, vero? In tutte le risposte si confronta una chiave con più colonne, più colonne hai bisogno di guardare più tempo ci vorrà. Non c'è un modo migliore? – Breno

+0

@Breno - L'unico altro modo in cui riesco a pensare è concatenare tutti i campi e quindi cercare quel nuovo campo. campi =: nome,: indirizzo_1,: indirizzo_2 Item.where ("concat_ws ('', # {fields.join (',')}) LIKE?", "% # {Chiave}%") –