Skip to content

Instantly share code, notes, and snippets.

@amolpujari
Last active April 18, 2020 06:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amolpujari/de43e414dd4d3b4d48bccccf17cdd509 to your computer and use it in GitHub Desktop.
Save amolpujari/de43e414dd4d3b4d48bccccf17cdd509 to your computer and use it in GitHub Desktop.
rails 5 elastic search kicksearch wrapper
# frozen_string_literal: true
module Searchable
module ApplicationRecordAddition
def search_on *method_names, &import_block
send :include, ::Searchable
scope :search_import, import_block if import_block
define_method :search_data do
method_names.inject({}) do |hash, attr|
hash[attr.to_s] = eval "#{attr}.to_s"
hash
end
end
end
end
extend ActiveSupport::Concern
LOGGER = Logger.new("#{Rails.root}/log/searchable.log")
included do
searchkick match: :text_middle
Searchable.add_model self
after_save :reindex
end
def reindex
return if ::Rails.env.stage?
return if (changes.keys & search_data.keys).blank?
self.class.reindex(async: true, refresh_interval: "30s")
end
def self.add_model val
@models ||= []
@models << val
end
def self.models
@models ||= []
end
def self.reindex
return if ::Rails.env.stage?
::Searchable.models.map do |model|
[model.name, model.reindex]
rescue => e
ExceptionNotifier.notify_exception e
if ::Rails.env.development?
::Rails.logger.error e.message
::Rails.logger.error e.backtrace.join("\r\n")
end
[model.name, e.message]
end
end
module ClassMethods
def searchable?
true
end
def search_ids q
t1 = Time.now
ids = search(q, load: false).pluck(:id)
t2 = Time.now
taken = "% 10.2f" % TimeDifference.between(t1, t2).in_ms
ids_count = "% 10d" % ids.count
q = "% 10s" % q
klass_name = "% 20s" % self.name
method_name = "% 20s" % __method__
::Searchable::LOGGER.info "|#{method_name}|#{klass_name}|#{q}|#{ids_count}|#{taken}|"
ids
end
end
end
ApplicationRecord.send :extend, ::Searchable::ApplicationRecordAddition
# and then in a model
class Request < ApplicationRecord
search_on :title, :status, :submitted_by do
includes(:submitted_by)
end
# in datatable
def apply_search
if search.present? && @data.searchable?
@data = @data.where id: @data.search_ids(search)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment