bga*_*oci 9 ruby search ruby-on-rails
我已经在rails上构建了一个带ruby的博客应用程序,我正在尝试实现搜索功能.博客应用程序允许用户标记帖子.标签是在自己的表格中创建的belong_to :post.创建标记时,标记表中的记录也是如此,其中标记的名称为tag_name并由post_id关联.标签是字符串.
我试图允许用户以任何顺序搜索任何单词tag_name.这就是我的意思.让我们说一个特定的帖子有一个标签是'红宝石代码控制器'.在我当前的搜索功能中,如果用户搜索"ruby","ruby code"或"ruby code controller",则会找到该标记.如果用户键入'ruby controller',则无法找到.
基本上我所说的是我希望在搜索中输入的每个单词都被搜索,而不一定是输入到搜索中的"字符串".
我一直在尝试提供多个文本字段以允许用户输入多个单词,并且还在使用下面的代码,但似乎无法完成上述操作.我是ruby和rails的新手很抱歉,如果这是一个明显的问题,在安装gem或插件之前,我想我会检查是否有一个简单的修复.这是我的代码:
查看:/views/tags/index.html.erb
<% form_tag tags_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search], :class => "textfield-search" %>
<%= submit_tag "Search", :name => nil, :class => "search-button" %>
</p>
<% end %>
Run Code Online (Sandbox Code Playgroud)
TagsController
def index
@tags = Tag.search(params[:search]).paginate :page => params[:page], :per_page => 5
@tagsearch = Tag.search(params[:search])
@tag_counts = Tag.count(:group => :tag_name,
:order => 'count_all DESC', :limit => 100)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @tags }
end
end
Run Code Online (Sandbox Code Playgroud)
标签模型
class Tag < ActiveRecord::Base
belongs_to :post
validates_length_of :tag_name, :maximum=>42
validates_presence_of :tag_name
def self.search(search)
if search
find(:all, :order => "created_at DESC", :conditions => ['tag_name LIKE ?', "%#{search}%"])
else
find(:all, :order => "created_at DESC")
end
end
end
Run Code Online (Sandbox Code Playgroud)
Har*_*tty 10
如果我正确读取了您的问题,如果该行的标记名称与查询字符串中传递的单词之一匹配,则您希望返回一行.
您可以search按如下方式重写方法:
def self.search(search)
all :conditions => (search ? { :tag_name => search.split} : [])
end
Run Code Online (Sandbox Code Playgroud)
如果您需要部分匹配,请执行以下操作:
def self.search(str)
return [] if str.blank?
cond_text = str.split.map{|w| "tag_name LIKE ? "}.join(" OR ")
cond_values = str.split.map{|w| "%#{w}%"}
all(:conditions => (str ? [cond_text, *cond_values] : []))
end
Run Code Online (Sandbox Code Playgroud)
编辑1 如果要传递多个搜索字符串,则:
def self.search(*args)
return [] if args.blank?
cond_text, cond_values = [], []
args.each do |str|
next if str.blank?
cond_text << "( %s )" % str.split.map{|w| "tag_name LIKE ? "}.join(" OR ")
cond_values.concat(str.split.map{|w| "%#{w}%"})
end
all :conditions => [cond_text.join(" AND "), *cond_values]
end
Run Code Online (Sandbox Code Playgroud)
现在您可以拨打电话,例如:
Tag.search("Ruby On Rails")
Tag.search("Ruby On Rails", "Houston")
Tag.search("Ruby On Rails", "Houston", "TX")
Tag.search("Ruby On Rails", "Houston", "TX", "Blah")
Tag.search("Ruby On Rails", "Houston", "TX", "Blah", ....) # n parameters
Run Code Online (Sandbox Code Playgroud)
警告:
通配符LIKE搜索效率不高(因为它们不使用索引).如果你有大量数据,你应该考虑使用Sphinx(通过ThinkingSphinx)或Solr(通过SunSpot).
| 归档时间: |
|
| 查看次数: |
9319 次 |
| 最近记录: |