Mam na podstawie railscastsa ‘simple search’ zrobione wyszukiwanie.
W railscascie jest jedno pole text_form i adres wygląda tak:
adres.pl/products?search=costam.
Potem widokwygląda tak:
def self.search(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
i OK.
Ja natomiast dodałem jeszcze kilka innych pół select.
I adres wyglada tak:
adres.pl/products?search=costam&category=2&place=3&comment=5
Jak teraz zgrabnie to wykonać, aby nie robic:
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
if category ....
if place .....
if comment ....
.....
end
end
end
I tak takim kodem nie zabezpiecze sie przed sytuacja gdy np category=nil.
Kombinacje wyszukiwania czy filtrowania (i ta i ta nazwa chyba dobra) moga być dowolne.
Jak to ładnie zapisać?
Myślałem o named_scopach i potem jakoś to zgrabnie łączyć. Tylko jak?
Liczę na jakieś sugestie.
A moze tez jakiś sposób na pozbycie sie tego mało eleganckiego adresu adres.pl/products?search=costam&category=2&place=3&comment=5.
Widziałem railscastsa 111 Advanced Search Form, ale jakoś nie podoba mi się ze zapisywane jest do bazy każde wyszukiwanie.
Jest taki fajny plugin Ryana Batesa scope_builder.
Używa się mniej więcej tak (w połączeniu z pluginem quick scopes, który udostępnia kilka dodatkowych: limit, where, with i order):
@articles = Article.scope_builder
@articles.where(:category_id => params[:category_id]) if params[:category_id]
@articles.where(['name LIKE ?', "%#{params[:query]}%"]) if params[:query]
@articles = @articles.paginate(:per_page => 20, :page => params[:page]
Jak potrzebujesz czegoś bardziej zaawansowanego, to zainteresuj się search logic.
UPDATE:
I oczywiście najlepiej to przerzucić do modelu, a kryteria mieć w jednym miejscu, na przykład:
{:search => {:query => “costam”, :category_id => 1, :foobar => 3}} tak, żeby można to było łatwo przekazać:
[quote=drogus]I oczywiście najlepiej to przerzucić do modelu, a kryteria mieć w jednym miejscu, na przykład:
{:search => {:query => “costam”, :category_id => 1, :foobar => 3}} tak, żeby można to było łatwo przekazać:
Article.search(params[:search]
[/quote]
Jak powinien wyglądać formularz aby taki efekt osiągnąć?
Zrobiłem tak:
<% end %>[/code]
Ale coś nie dizała bo wrzuca mnie na stronę z dodawaniem nowego artykułu.
A jak chciałbym, aby adres wyglądał tak: localhost:3000/articles/search
i potem postem wysłać parametry?
Tylko że tu potrzeba jeszcze :id artykułu aj ja go nie będę przecież miał.
Póki co mam działające wyszukiwanie ale z adresem
localhost:3000/articles?category=3&maker=1&tags=polska
i w kontrolerze
kupa ifów sprawdzających czy dane pole wybrane.
Wiem okropnie to wygląda i chcę to poprawić.
a chciałbym http://localhost:3000/developments/search
Oto mój okropmny kontroler:
def index
if params[:category].blank? and params[:maker].blank? and params[:tags].blank?
@articles= Article.all.paginate(:page => params[:page], :per_page => 5)
else
if params[:tags].blank?
@articles= Article.category(params[:category]).maker(params[:maker]).paginate(:page => params[:page], :per_page => 5)
else
@articles= Article.category(params[:category]).maker(params[:maker]).find_tagged_with(params[:tags].downcase, :match_all => true).paginate(:page => params[:page], :per_page => 5)
end
end
end
Bleee
hmn, też mam mały kłopot z tym simple search’em, chodzi mi o to, że mam listę postów, gdzie m.in. wyświetlane są kategorie. Chciałbym aby po kliknięciu w kategorie wyświetlały się wszystkie posty o danej kategorii, ale nie wiem jak przekazać parametr do metody search przez kliknięcie w link - chodzi mi o coś takiego:
<% link_to nazwalinku, lista_postów (wyświeltana poprzez właśnie tą metodę search, w przypadku gdy nie ma podanych żadnych argumentów wyświetla mi wszystkie posty ładnie), parametr_potrzebny_metodzie_search %>
Jak sprawić, aby ten parametr został przekazany metodzie search?
A, i mój search w modelu wygląda tak:
def self.search(search)
if search
find(:all, :conditions => ['category LIKE ?', "#{search}%"])
else
find(:all)
end
end
EDIT: