Search code examples
activerecordelasticsearchdelayed-job

How to index ActiveRecord models async with Elasticsearch gem and delayed_job


How do i use elasticsearch to index async similar to the sidekiq example

I am using delayed_job instead of sidekiq.


Solution

  • Create a searchable concern and a special indexer class (i put it in lib/indexer.rb) that works with any ActiveRecord model and finds by ID.

    concerns/searchable.rb

    require 'elasticsearch/model'
    
    module searchable
      extend activesupport::concern
    
      included do
        include elasticsearch::model
        after_touch() {indexer.delay.update(self.class.name, id)}
    
        after_commit lambda {indexer.delay.create(self.class.name, id)},  on: :create
        after_commit lambda {indexer.delay.update(self.class.name, id)},  on: :update
        after_destroy lambda {indexer.delay.delete(self.class.name, id)}
      end
    
    end
    

    lib/indexer.rb

    class Indexer
      def self.create(klass_name, id)
        doc = klass_name.constantize.find(id)
        doc.__elasticsearch__.index_document
      end
    
      def self.update(klass_name, id)
        doc = klass_name.constantize.find(id)
        doc.__elasticsearch__.update_document
      end
    
      def self.delete(klass_name, id)
        # it's already deleted, so we have to delete it old school
        doc = klass_name.constantize.new
        doc.id = id
        doc.__elasticsearch__.delete_document 
      end
    
    end