2013-05-23 15 views
11

To może być bardziej składnia Ruby niż cokolwiek innego. Mam trudności z uzyskaniem dwóch warunków ograniczających dla SomeObject.find.Rails ActiveRecord: Wiele warunków w znalezieniu

separacji, warunki wydają się działać:

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

Co Idę za pierwszym przypadku jest to:

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

Ale linia rzutów syntax error, unexpected ')', expecting tASSOC.

Odpowiedz

16

szyn 2

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1]) nie jest właściwa składnia przechodzącej skrótów sposobu. Możesz zostawić nawiasy klamrowe z skrótu, jeśli jest to ostatni argument metody, ale w tym przypadku przekazujesz tablicę jako ostatni argument.

Użyj następującego zamiast:

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

lub

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

Szyny 3 i 4

Pewnie można chcieć zrobić coś więcej jak poniżej dla najnowszych wersji Rails:

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

A potem by nazwać tak:

YourModel.active.name_like("Bunnies") 

To pozwala na ponowne użycie tych konkretnych zapytań w różnych kombinacjach w całej aplikacji. Dzięki temu kod odczytujący dane jest bardzo łatwy do odczytania.

Jeśli nie podoba składni scope, można również zdefiniować je jako metody klasy:

def self.active 
    where(active: true) 
end 

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

można również zakresy łańcuch na bieżąco. Umożliwi to rozpoczęcie budowania łańcucha obiektów relacji, a następnie włączenie innych w zależności od warunków.Oto, co to może wyglądać, gdy zastosowane do pierwotnego pytania, aby osiągnąć takie same wyniki:

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

Dziękuję bardzo! Twój drugi przykład pracował dla mnie (nie próbował pierwszego - drugi wygląda jak fajny sposób na dodanie dowolnej liczby warunków, więc nie muszę się martwić o ich kolejność tak bardzo). –

2

Zamiast if-else która wiązałaby się redundancję dla sprawdzania active = 1, prostsza składnia byłoby coś takiego:

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

miarę błędu Twój widzenie, to nie wydaje się być spowodowana przez kod, który publikujesz. Ślad stosu może pomóc sprowadzić dalej ...

+0

Tak, jakbym zatrzymać się tu, byłoby to rodzaj zbędne, ale chcę zrobić takie rzeczy jak tylko Shuffle wyniki jeśli nie ciąg wyszukiwania został wpisany i chcę dodać dodatkowe warunki/oświadczenia na temat tego fundamentu. Dzięki za odpowiedź! –

2

myślę używasz szyn 2

spróbować.

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

szyny 3 składni

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

Używam Rails 3, ale otrzymałem oryginalny fragment wyszukiwania z samouczka z 2007 roku: http://railscasts.com/episodes/37-simple-search-form –

0

dla szyn 4, w szynach nowy find_by i find_by! Metody są wprowadzane

Read answer