2013-05-23 20 views
11

Questa potrebbe essere più di una cosa sulla sintassi Ruby che altro. Sto avendo difficoltà a ottenere due condizioni limitanti su SomeObject.find.Rails ActiveRecord: più condizioni di ricerca

Separato, le condizioni sembrano funzionare:

if search != '' 
    find(:all, :conditions => ['name LIKE ?', "%#{search}%"]) 
else 
    find(:all, :conditions => ['active', 1]).shuffle 
end 

Quello che sto andando per per il primo caso è questo:

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1]) 

Ma la linea di tiri syntax error, unexpected ')', expecting tASSOC.

risposta

16

rotaie 2

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1]) non è la sintassi corretta per il passaggio hash a un metodo. Puoi lasciare le parentesi graffe fuori da un hash se è l'ultimo argomento di un metodo, ma in questo caso stai passando un array come ultimo argomento.

Utilizza il seguente invece:

find(:all, :conditions => ["name LIKE ? AND active = ?", "%#{search}%", 1]) 

o

params = {:search => "%#{search}%", :active => 1} 
find(:all, :conditions => ["name LIKE :search AND active = :active", params]) 

Rails 3 e 4

si sarebbe probabilmente vuole fare qualcosa di più simile al seguente per le versioni Rails recenti:

scope :active, -> { where(active: true) } 
scope :name_like, ->(search) { where("name LIKE ?", "%#{search}%") } 

E poi si definirebbe così:

YourModel.active.name_like("Bunnies") 

che permette di riutilizzare tali query specifiche in diverse combinazioni in tutta l'applicazione. Rende anche il codice che recupera i dati super facile da leggere.

Se non ti piace la sintassi scope, è anche possibile definire queste come metodi di classe:

def self.active 
    where(active: true) 
end 

def self.name_like(search) 
    where("name LIKE ?", "%#{search}%") 
end 

si può anche ambiti di catena al volo. Ciò ti consentirà di iniziare a costruire una catena di oggetti relazionali e poi scegliere di includerne altri in base alle condizioni.Ecco quello che potrebbe apparire come se applicato alla domanda iniziale per ottenere gli stessi risultati:

results = active 
results = results.name_like(search) if search.present? 
+0

Grazie mille! Il tuo secondo esempio ha funzionato per me (non ho provato il primo - il secondo sembra un bel modo per aggiungere un numero qualsiasi di condizioni in modo da non dovermi preoccupare del loro ordine così tanto). –

2

Invece di usare if-else che comporterebbe una ridondanza per il controllo su active = 1, una sintassi più semplice sarebbe qualcosa di simile:

result = where(:active => 1) 
result = result.where('name like ?', "%#{search}%") unless search.blank? 

Per quanto riguarda l'errore tua vedere, non sembrerebbe essere causato dal codice che stai postando. Una traccia di stack può aiutare a restringere ulteriormente verso il basso ...

+0

Sì, se fossi fermarsi qui, sarebbe una sorta di ridondante, ma voglio fare le cose come solo Shuffle i risultati, se è stato inserito alcun testo da cercare e voglio aggiungere ulteriori condizioni/dichiarazioni in cima a questa fondazione. Grazie per la tua risposta! –

2

penso che si utilizza rotaie 2

provare questo.

find(:all, :conditions => ['name LIKE ? and active = 1', "%#{search}%"]) 

rotaie 3 sintassi

where('name LIKE ? and active = 1', "%#{search}%") 
+0

Sto usando Rails 3, ma ho ottenuto lo snippet di ricerca originale da un tutorial del 2007: http://railscasts.com/episodes/37-simple-search-form –

0

per Rails 4, in Rails nuova find_by e find_by! metodi sono introdotti

Read answer

Problemi correlati