有没有更好的方法来编写这个named_scope? [滑轨]

时间:2010-09-05 22:35:36

标签: ruby-on-rails ruby idioms

我正在使用此named_scope来搜索具有与用户输入的任何单词匹配的描述的产品。

,例如Product.description_like_any("choc pret")

将返回名称为

的产品
  • “巧克力棒”
  • “巧克力覆盖的椒盐卷饼”
  • “迷你巧克力小马”

这是我写过的named_scope(有效)

named_scope :description_like_any, (lambda do |query|
  return {} unless query
  conditions = []
  values = []
  for q in query.split(/\s+/)
    conditions << "(`products`.description LIKE ?)"
    values << "%#{q}%"
  end
  { :conditions => [conditions.join(' AND '), *values] }
end)

有没有更好的方法来写这个?也许我错过了一两个Rubyism / Railism?

解决方案

scope_procedure与Searchlogic结合使用,可以更简单的方式完成。请注意,该解决方案甚至可以利用Searchlogic的_or_语法将两个范围连接在一起。 :keywords scope_procedure找到符合product.descriptionproduct.vendor.name的商品;全部都有一个文本字段!

模型

# app/models/product.rb
class Product < ActiveRecord::Base
  scope_procedure :keywords, lambda |query|
    description_like_any_or_vendor_name_like_any(query.split(/\s+/))
  end
end

控制器

# app/controllers/products_controller.rb
class ProductsController < ApplicationController
  def index
    @search = Product.search(params[:search])
    @products = @search.all
  end
end

浏览

# app/views/products/index.html.erb
<% form_for @search do |f| %>
  <%= f.label :keywords, "Quick Search" %>
  <%= f.input :keywords %>
  <%= f.submit, "Go" %>
<% end %>

1 个答案:

答案 0 :(得分:3)

最棘手的事情就是不要自己写这个。 :-)使用优秀的Searchlogic gem,它将为您创建description_like_any范围。

编辑:如果您希望用户能够在这样的自由文本字段中输入搜索字词,您可以定义自己的范围:

class Product < ActiveRecord::Base
   # ...
   scope_procedure :description_like_any_term, lambda { |terms| 
     name_like_any(terms.split(/\s+/))
   }
   # ...
end