Last active
July 9, 2018 07:13
-
-
Save BideoWego/4dfa80f920c305d3cac6f0abf2fc13c4 to your computer and use it in GitHub Desktop.
Model Searchable concern for Rails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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