6

Kullanıcı adı, son_adı ve ilk addaki bir dizgiyi kontrol etmesi gereken basit bir arama fonksiyonu yapıyorum. Ben eski bir RailsCast bu ActiveRecord yöntemi gördüm: o isim, LAST_NAME ve birinci adına anahtar kelimeyi arayıp eğer kayıt döndürmesini sağlayacak şekildeRails ActiveRecord - Çoklu Özelliklerde Ara

http://railscasts.com/episodes/37-simple-search-form

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

Ama bunu nasıl yapabilirim Tarlalardan biri terimle eşleşti?

Ayrıca RailsCast üzerindeki kodun SQL enjeksiyonlarına eğilimli olup olmadığını merak ediyorum?

Çok teşekkürler! Ben senin model adını kabul

cevap

20

Modeli - eğer gerçek sorgu yaptığınızda sadece gerçek modeli adı ile değiştirin: SQL yerleştirme hakkında endişe Hakkında

Model.where("name LIKE ? OR last_name LIKE ? OR first_name LIKE ?", "%#{search}%","%#{search}%","%#{search}%") 

- kod parçacıkları hem SQL enjeksiyonu için bağışıklık . WHERE yan tümcesine doğrudan dizeleri yerleştirmediğiniz sürece sorun yoktur. Enjeksiyon eğilimli kodu için bir örnek olacaktır:

Model.where("name LIKE '#{params[:name]}'") 
+0

Sadece ihtiyacım olan şey. Açıkça açıkladığın için teşekkürler! – maru

+0

Denetleyici, yalnızca "params [: search]" yerine tüm "params" i değiştirecek şekilde değiştirilirse ve "% # {params [: search]}%" 'yerine"% # "kullanırız. {ara}% " '. Bu hala SQL enjeksiyonlarına bağışık mı? – Dennis

+0

@Dennis evet öyle. Kullandığın sürece? ve sorgunuzda bunları değiştirmek için ekstra argüman geçiyorsunuz. –

8

seçilen cevap çalışacak olsa da, ben bunu iki durumda başarısız olur, çünkü bir arama "Raul Riera" yazmak çalışırsanız o kırar fark Raul çünkü Riera ya benim ilk isim ya da benim son adı değil .. benim ilk ve son isim ... bunu yapmak için

Model.where("lower(first_name || ' ' || last_name) LIKE ?", "%#{search.downcase}%") 
+0

Bu cevabı daha yararlı buldum. Teşekkürler! –

+0

Aşağıdan ziyade "ILIKE" kullanmak daha iyi olmaz mıydı? DB halledelim. –

+0

Last_name veya first_name nil değerine eşit olduğunda işe yaramıyor, eğer öyleyse, varsayılan boş dize değerini ilk ve son ad olarak ayarlamanız gerekir –

0

iyi yolu yaparak çözdü geçerli:

Model.where("attr_a ILIKE :query OR attr_b ILIKE :query", query: "%#{query}%") 
0

ile Arel, yazmayı bırakabilirsin El ile böyle bir şey ile SQL: alanları listesi dinamik idi karşı maç için eğer

Model.where(
    %i(name first_name last_name) 
    .map { |field| Model.arel_table[field].matches("%#{query}%") 
    .inject(:or) 
) 

Bu özellikle yararlı olacaktır.

İlgili konular