Sortowanie według trafności

Witam!
Mam wyszukiwarkę, do której wpisujemy tagi.
Zmienna @products zawiera wszystkie produkty, które mają przynajmniej 1 z wyszukiwanych tagów.
Zmienna @tags przechowuje tagi które zostały wpisane w wyszukiwarce.
Używam pluginu acts_as_taggable_on.

@products = Product.tagged_with(params[:search].split(/,?\s/), :on => :tags) @tags = Tag.find(:all, :conditions => {:name => params[:search].split(/,?\s/)})
Każdy produkt ma kilka tagów.
Pytanie:
Jak posortować produkty aby były w kolejności wg trafności, tzn (pseudokod) : jeżeli wszystkie tagi danego produktu zawierają się w @tags produkt będzie pierwszy w kolejności, itd, według brakujących tagów.

@policzone = Tagging.count(:all, :group => :taggable_id, :conditions => {:tag_id => @tags})

Zmienna zawiera tablice [ id produktu, liczba pasujących tagów]

Jedyne co mi przychodzi na myśl to porównanie liczby tagów produktu i liczby pasujących tagów. Ale ciągle nie wiem jak to zapisać.

Z góry dzięki!

A czy przypadkiem nie będzie tu można użyć full text search, który od razu posortuje Ci wyniki według trafności?

Full text tu się raczej nie nadaje. Chodzi mi tu o znajdowanie konkretnych tagów a nie textu.

Skoro się upierasz ;). Ja bym tak jechał, ale skoro chcesz inaczej, to widzę też inaczej. Na pewno masz możliwość korzystania z tablic tagów danego produktu i tagów wyszukiwanych. Tę pierwszą nazwiemy prod_tags, drugą search_tags. Mając @products, w których mamy każdy wynik z choć jednym tagie, to dla każdego z jego elementów tworzymy prod_tags. Następnie łączymy go z tablicą search_tags i patrzymy jaki ma rozmiar. Następnie usuwamy powtarzające się elementy i znów patrzymy rozmiar. W ten sposób wiemy ile tagów było znalezionych w danym produkcie. I dalej to już chyba wiesz jak jechac?

prod_tags << search_tags found_counter = prod_tags.size - prod_tags.uniq.size
p.s. nie wiem czy nie ma metody łączącej tablice, która od razu pozbywa się duplikatów. Ale to jak mówie nie wiem, musisz sam sprawdzić

Dałbym sobie jajko uciąć, że bardzo podobna kwestia była na forum roztrząsana niecały tydzień temu (czwartek).

EDIT: o, jest
http://rubyonrails.pl/forum/t1993-Wyszukiwarka%2C-auto_complete
i nawet autor ten sam :wink:

[quote=Tomash]Dałbym sobie jajko uciąć, że bardzo podobna kwestia była na forum roztrząsana niecały tydzień temu (czwartek).

EDIT: o, jest
http://rubyonrails.pl/forum/t1993-Wyszukiwarka%2C-auto_complete
i nawet autor ten sam ;)[/quote]
Bo ciągle problem nie został rozwiązany

[quote=Piotr Misiurek]Skoro się upierasz ;). Ja bym tak jechał, ale skoro chcesz inaczej, to widzę też inaczej. Na pewno masz możliwość korzystania z tablic tagów danego produktu i tagów wyszukiwanych. Tę pierwszą nazwiemy prod_tags, drugą search_tags. Mając @products, w których mamy każdy wynik z choć jednym tagie, to dla każdego z jego elementów tworzymy prod_tags. Następnie łączymy go z tablicą search_tags i patrzymy jaki ma rozmiar. Następnie usuwamy powtarzające się elementy i znów patrzymy rozmiar. W ten sposób wiemy ile tagów było znalezionych w danym produkcie. I dalej to już chyba wiesz jak jechac?

prod_tags << search_tags found_counter = prod_tags.size - prod_tags.uniq.size
p.s. nie wiem czy nie ma metody łączącej tablice, która od razu pozbywa się duplikatów. Ale to jak mówie nie wiem, musisz sam sprawdzić[/quote]
Ok, zgadzam się ale ciągle jesteśmy na etapie nie posortowanych wyników. Jak dołączyć liczby pasujących tagów do produktów?

Ja bym dodał do modelu metode, która sprawdza jak się zgadza dany produkt z podaną jako argument frazą tagów do wyszukania. A mając tę metodę, pojechał bym z sort_by w oparciu o nią

Idealnie!

model

def missings(tagi) i = tags.count for tag in tags if tagi.include?(tag.to_s) i-=1 end end return i end
controller

@products = Product.tagged_with(params[:search].split(/,?\s/), :on => :tags).sort_by{|i| i.missings(@tags)}

Dzięki!