文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Ruby on Rails: Using Full Text Search with Tagging

Ruby on Rails: Using Full Text Search with Tagging

时间:2008-01-17  来源:linxh

 本文转自: http://www.inu.cc/catch/18810/catch.html  

Ruby on Rails: Using Full Text Search with Tagging

Sunday, August 27, 2006

I’m working on a new application in Rails that uses both Tagging as well as full text indexing. I decided to go with Ferret, which is just a Ruby port of Lucene. Using the acts_as_ferret plugin, it’s dead simple to integrate into your application. First, you want to install Ferret on your machine, and then run this command:

script/plugin install svn://projects.jkraemer.net/acts_as_ferret /tags/stable/acts_as_ferret 

At this point, you are ready to start enabling searching on your objects. Let’s say you want to enable full text search through a list of blog posts in your application. All you need is to add the acts_as_ferret line to your model class.

class Post < ActiveRecord::Base acts_as_ferret end 

And there you have it, full text indexing is enabled. To search through your objects, you’ll do nothing more than this:

Post.find_by_contents("Agile Rails") 

That’s pretty much it. Dead Simple!  So now we require tagging support for our application, because it’s much easier to find a post if it’s tagged with “Agile Ruby Rails“. Here’s where I had a few issues, because it seems like there are any number of different tagging plugins/mixins/whatever out there. I ended up taking the most simple one, as I figure I’ll add in my own features as I go along anyway. I ended up going with the ActsAsTaggable Plugin, mostly because I found it on the official Rails Wiki. This plugin was every bit as simple to install…

script/plugin install acts_as_taggable script/generate migration add_tag_support 

In case you are unfamiliar, the second line generates a Rails Migration, which lets you create your database tables with Ruby code. It fits into the overall Rails framework a lot better, so I’ve been using it. If you don’t use it, you’ll need to create a set of tables mimicing what the Ruby code is meant to do. Add this to the add_tag_support_0xx.rb file that is created by the last command.

class AddTagSupport < ActiveRecord::Migration def self.up #Table for your Tags  create_table :tags do |t| t.column :name, :string end create_table :taggings do |t| t.column :tag_id, :integer #id of tagged object  t.column :taggable_id, :integer #type of object tagged  t.column :taggable_type, :string end end def self.down drop_table :tags drop_table :taggings end end 

Now you add the acts_as_taggable to your model class

class Post < ActiveRecord::Base acts_as_ferret acts_as_taggable end 

Here’s some sample code to get you started:

# tags a post with both the tags "Agile" and "Rails"  post.tag_with("agile rails") # returns a string containing "agile rails", space delimited.  post.tag_list # find all posts tagged with Rails  post.find_tagged_with("Rails")  

Let’s recap. We installed Ferret, the acts_as_ferret plugin, and the acts_as_taggable plugin. At this point we have both tagging support as well as the ability to full text search through our objects as simply as doing Post.find.

But there’s a problem! I’ve tagged my post with “development”, but when I type that into my search box, nothing is coming up…

The issue is that the acts_as_ferret plugin is not indexing the tags, just the Post object. There’s some way to override the default handling by overriding the todoc method, but I haven’t gotten that far yet, and it just seems like overkill to redo this whole plugin just because I want to search the tags. So I’ve come up with a simpler solution: Add a new column to my model containing the list of tags. Sure, this violates the DRY principle, but I’m betting it also helps performance, not to mention my sanity. The other thought I had was that I don’t want to maintain a custom version of this plugin if I don’t have to. If, or when, a new version of these two plugins comes out, I’d like to be able to just do a straightforward upgrade.

So, I added a new column to my Post model and called it Taglist. When I save the tags using tag_with(), I also save the list of tags into the taglist object. This is really the only duplicated piece of code, but it’s just a one-liner. I’m sure there’s a better way to override the default behavior, but this method was quicker. And now, I can find items when I search for “Development”.  Ferret is soooooooo fast!

Here’s a quick list of the packages I used:

  • ActsAsTaggable Plugin
  • Ferret
  • acts_as_ferret plugin

Enjoy.

Update: I mistakenly had put acts_as_taggable in this next line, when I meant to put acts_as_ferret

Update (again): The correct syntax for specifying the fields is like this:

acts_as_ferret :fields=>[”fieldname”,”otherfield”,:tag_list]

That works perfectly, thanks to John Gray in the comments box

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载