2009-04-23 52 views
1

我正在使用rails的acts_as_tsearch插件来使用Postgresql进行全文搜索。SQL搜索与acts_as_tsearch多对多的关系

他们给这里多表搜索的例子: http://code.google.com/p/acts-as-tsearch/wiki/ActsAsTsearchMethod

但这只做一个一对多的关系。我试图让它也为页面上的标签搜索多对多关系(has_and_belongs_to_many或habtm)。但是我的SQL不够先进。

这里是我到目前为止有:

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')))" 
     } 
    } 
    } 

我不知道如何引用页面ID(这里我把???)。

感谢您的帮助!

+0

你能解释一下taggable_id的用途吗? – Andomar 2009-04-23 07:37:52

回答

1

那么,这背后的SQL将是:

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 

所以,你的红宝石看起来像:

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" 
    } 
    } 
} 

这是标准的方式,通过一个多到多表得到 - 从一个表开始,加入映射,然后加入另一个表。瞧!多对多的结果!