浏览 5732 次
锁定老帖子 主题: acts_as_ferret
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-04-26
下载ferret.gem , acts_as_ferret plugin gem : gem insatall ferret plugin : svn://projects.jkraemer.net/acts_as_ferret/trunk/plugin/acts_as_ferret,直接check out下来放到vendor/plugin 目录下即可 现有一个model: class Provider< ActiveRecord::Base ....... ................... acts_as_ferret :fields => [:name,:description,:address,:website,:score,:phone,:direction] .......... ............ end 这里:fields就是要进行索引的对象属性了,当然你也可以不指定,直接就一句"acts_as_ferret",默认不指定的时候是对所有列进行索引,先时事效果: >>ruby script/console >>Provider.find_by_contents(" 你要 搜索 的内容") OK,如果没有意外的话, 结果会返回一个ActsAsFerret::SearchResults对象。如果出错了,回过去检查一下,短短几步,检查起来也应该很方便。 几个tip: # "关键词1" AND “关键词2” Provider.find_by_contents(" 关键词1 关键词2") #"关键词1" OR "关键词2" Provider.find_by_contents("关键词1 OR 关键词2") #貌似“关键词1”的结果 Provider.find_by_contents("关键词1~") 上面这几个都是小儿科啦 下面我们到acts_as_ferret plugin内部去看看, acts_as_ferret/lib 瞄到 acts_as_ferret.rb 第116行(VERSION=181) “ActiveRecord::Base.extend ActsAsFerret::ActMethods” 许多blog中都建议在要进行分词查询的model中加入下面一段代码: def full_text_search(q, options = {}) return nil if q.nil? or q.strip.blank? default_options = {:limit => 10, :page => 1} options = default_options.merge options options[:offset] = options[:limit] * (options.delete(:page).to_i-1) results = self.find_by_contents(q, options) [results.total_hits, results] end 不过,本着DRY的原则,我决定从“ActiveRecord::Base.extend ActsAsFerret::ActMethods”这句话上做文章,既然ActiveRecord::Base 继承了 ActsAsFerret::ActMethods ,何不将这段代码加入到ActMethods里去,让所有model都拥有 full_text_search的功能? module ActsAsFerret #:nodoc: # This module defines the acts_as_ferret method and is included into # ActiveRecord::Base module ActMethods def full_text_search(q, options = {}) return nil if q.nil? or q.strip.blank? default_options = {:limit => 10, :page => 1} options = default_options.merge options options[:offset] = options[:limit] * (options.delete(:page).to_i-1) results = self.find_by_contents(q, options) [results.total_hits, results] end ................ .................... end end 重启一下,Provider.full_text_search方法应该出来了,有问题的话自己回去检查看看 下面就是俗套,在application.rb中加入: def pages_for(size, options = {}) default_options = {:per_page => 10} options = default_options.merge options pages = Paginator.new self, size, options[:per_page], (params[:page]||1) pages end 这些种种工作都是为了在controller以及view中调用: controller: def search @query=params[:query] <%= pagination_links(@pages, :params => {:query=>@query}) %> 关于 find_by_contents(q, options = {}, find_options = {}) 中的find_options,考虑一下一种情况: provider表结构: id name description category_id 如果要对特定category_id的数据进行检索,应如何?这里就用到了find_option了: 代码: Vendor.find_by_contents(" 要进行检索的关键字 ",{:limit=>30},{:joins=>"providers join categories on providers.category_id = categories.id ", :conditions =>" providers.category_id = XXXXX "}) 其他一些小技巧大家可以到到网上找找,这里就不一一列举了。 ========================================================================================= acts_as_ferret :fields => { :name => {}, :address => {}, :website => {}, :score => {:index=> :untokenized, :term_vector => :no ,:boost=>10}, :vote_count => {:index=> :untokenized, :term_vector => :no,:boost=>5}, :category_name=>{}, :tag_name=>{}, :taste => {:index => :untokenized}, :service => {:index => :untokenized}, :environment => {:index => :untokenized}, :deal => {:index => :untokenized}, } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |