Skip to content

Instantly share code, notes, and snippets.

@BideoWego
Last active July 9, 2018 07:13
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BideoWego/4dfa80f920c305d3cac6f0abf2fc13c4 to your computer and use it in GitHub Desktop.
Save BideoWego/4dfa80f920c305d3cac6f0abf2fc13c4 to your computer and use it in GitHub Desktop.
Model Searchable concern for Rails
module Searchable
def self.included(base)
base.extend(ClassMethods)
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
class User < ActiveRecord::Base
include Searchable
searchable_scope ->(q){where("first_name || ' ' || last_name LIKE ?", "%#{q}%")}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment