最短的答案是将此方法标记到您的模型上:
def search_by_fields(q, fields=nil)
sql = fields.map {|field| "#{field} LIKE ?"}.join(' OR ')
parameters = fields.map {"%#{q}%"}
where(sql, *parameters)
end
问题的答案更长!
使用关注点是为您选择的任何模型提供搜索功能的好方法。看一下这个。首先在您的app/models/concerns/ 中创建一个名为searchable.rb 的文件,代码如下:
#app/models/concerns/searchable.rb
module Searchable
def self.included(base)
base.extend(ClassMethods)
base.include(AdapterAcknowledgeable)
end
module ClassMethods
@@searchable_fields = []
@@searchable_scope = nil
def search(q, method=nil)
search_method = resolve_search_method(method)
self.send(search_method, q)
end
def search_by_fields(q, fields=nil)
fields = searchable_fields unless fields
sql = fields.map {|field| "#{field} LIKE ?"}.join(' OR ')
parameters = fields.map {"%#{q}%"}
where(sql, *parameters)
end
def search_by_scope(q, scope=nil)
scope = searchable_scope unless scope
scope.call(q)
end
def searchable_scope(scope=nil)
@@searchable_scope = scope unless scope.nil?
@@searchable_scope
end
def searchable_fields(*fields)
@@searchable_fields = fields if fields.present?
@@searchable_fields
end
private
def resolve_search_method(method)
method = method.downcase.to_sym unless method.nil?
if method == :searchable_fields ||
searchable_fields.present? && searchable_scope.nil?
:search_by_fields
elsif method == :searchable_scope ||
!searchable_scope.nil? && searchable_fields.empty?
:search_by_scope
else
raise "Unable to determine search method within #{self}, you must declare exactly one search method in the including class"
end
end
end
end
用法如下:
这将使foo、bar、fiz 和baz 的所有列能够通过 SQL WHERE LIKE 进行查询。通过将它们与OR 连接起来,它允许它们中的任何一个匹配查询参数。
#app/models/my_searchable_model.rb
class MySearchableModel < ActiveRecord::Base
include Searchable
searchable_fields :foo, :bar, :fiz, :bad
end
该关注点还允许您使用 Ruby 的 lambda 语法指定范围,如下所示:
class User < ActiveRecord::Base
include Searchable
searchable_scope ->(q){where("first_name || ' ' || last_name LIKE ?", "%#{q}%")}
end
注意使用 SQL 连接运算符||。
现在,当我们要搜索包含关注点的模型时:
MySearchableModel.search('foo')