2009-04-23 8 views
1

Ich benutze das Acts_as_tsearch Plugin für Schienen, um Volltextsuche mit Postgresql zu tun.SQL zum Suchen vieler zu vielen Beziehung mit acts_as_tsearch

Sie geben ein Beispiel für Multi-Table-Suche hier: http://code.google.com/p/acts-as-tsearch/wiki/ActsAsTsearchMethod

Aber das nur eine Beziehung Eins-zu-viele der Fall ist. Ich versuche, es auch eine Viele-zu-Viele-Beziehung (has_and_belongs_to_many oder hattm) für Tags auf einer Seite zu suchen. Aber mein SQL ist nicht fortgeschritten genug. Hier

ist das, was ich bisher habe:

acts_as_tsearch :vectors => { 
    :fields => { 
     "a" => {:columns => ["pages.name"], :weight => 1.0}, 
     "b" => {:columns => ["pages.description"], :weight => 0.2}, 
     "c" => {:columns => ["tags.name"], :weight => 0.2} 
    }, 
    :tables => { 
     :tags => { 
     :from => "tags INNER JOIN taggings ON tags.id = taggings.tag_id", 
     :where => "((taggings.taggable_type = 'Page') AND (taggings.taggable_id = ???.id) AND ((taggings.context = 'tags')))" 
     } 
    } 
    } 

Ich bin nicht sicher, wie die Seiten-ID referenzieren (wo ich das ??? setzen).

Danke für Ihre Hilfe!

+0

Können Sie erklären, wofür eine taggable_id verwendet wird? – Andomar

+0

Gute Frage, sorry, ich hätte es erklären sollen. Es ist polymorph, also bezieht sich taggable_id auf jedes Modell, das Tags haben kann. In diesem Fall könnte es page_id genannt werden, da nur meine Seiten Tags haben, aber sie haben es polymorph gemacht, so dass jedes Modell Tags haben kann. Grundsätzlich enthält die Tabelle "Tags" die IDs für Seiten und Tags, um die Viele-zu-Viele-Beziehung zu verbinden. Danke für Ihre Hilfe! –

Antwort

1

Nun, die SQL dahinter wäre:

select 
    p.name, 
    p.description, 
    t.name 
from 
    pages p 
    inner join taggings ts on 
     p.page_id = ts.taggable_id 
     and ts.taggable_type = 'Page' 
     and ts.context = 'tags' 
    inner join tags t on 
     ts.tag_id = t.tag_id 

Also, Ruby würde wie folgt aussehen:

acts_as_tsearch :vectors => { 
    :fields => { 
    "a" => {:columns => ["p.name"], :weight => 1.0}, 
    "b" => {:columns => ["p.description"], :weight => 0.2}, 
    "c" => {:columns => ["t.name"], :weight => 0.2} 
    }, 
    :tables => { 
    :tags => { 
     :from => "pages p 
     inner join taggings ts on 
      p.page_id = ts.taggable_id 
      and ts.taggable_type = 'Page' 
      and ts.context = 'tags' 
     inner join tags t on 
      ts.tag_id = t.tag_id" 
    } 
    } 
} 

Dies ist der normale Weg durch eine many-to-many-Tabelle zu erhalten - Beginnen Sie einfach an einem Tisch, treten Sie dem Mapping bei und verbinden Sie sich dann mit dem anderen Tisch. Voila! Viele-zu-viele Ergebnisse!

Verwandte Themen