最简单的方法是将此方法添加到您的模型中:
def search_by_fields(q, fields=nil)
sql = fields.map {|field| "#{field} LIKE ?"}.join(' OR ')
parameters = fields.map {"%#{q}%"}
where(sql, *parameters)
end
有一个更详细的答案需要关注!
使用concern是为您选择的任何模型提供搜索功能的好方法。看看这个。首先,在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
将它们连接起来,允许任何一个与查询参数匹配。
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')