有没有更好的方法来编写这个named_scope? [导轨]
我正在使用此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.description
或 product.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 %>
I am using this named_scope to search for products that have a description matching any word the user inputs.
E.g., Product.description_like_any("choc pret")
Will return products with names like
- "Chocolate Bar"
- "Chocolate Covered Pretzels"
- "Miniature Chocolate Ponies"
Here's the named_scope I've written (which works)
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)
Is there a better way to write this? Perhaps I'm missing a Rubyism/Railism or two?
Solution
Using scope_procedure
in conjunction with Searchlogic, this can be done in an even easier way. Note, the solution before even leverages Searchlogic's _or_
syntax for connecting two scopes together. The :keywords
scope_procedure finds products matching product.description
, or product.vendor.name
; All with one text field!
Model
# 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
Controller
# app/controllers/products_controller.rb
class ProductsController < ApplicationController
def index
@search = Product.search(params[:search])
@products = @search.all
end
end
Views
# app/views/products/index.html.erb
<% form_for @search do |f| %>
<%= f.label :keywords, "Quick Search" %>
<%= f.input :keywords %>
<%= f.submit, "Go" %>
<% end %>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最Railsy 要做的事情就是不要自己写这个。 :-) 使用优秀的 Searchlogic gem 它将创建
description_like_any
范围你。编辑:如果您希望用户能够在这样的自由文本字段中输入搜索词,您可以定义自己的范围:
The most Railsy thing to do is to not write this yourself. :-) Use the excellent Searchlogic gem which will create the
description_like_any
scope for you.Edit: If you want your user to be able to enter search terms in a free text field like this, you can define your own scope: