module Searchable extend ActiveSupport::Concern SEARCH_CONTENT_LIMIT = 32.kilobytes included do after_create_commit :create_in_search_index after_update_commit :update_in_search_index after_destroy_commit :remove_from_search_index end def reindex update_in_search_index end private def create_in_search_index if searchable? search_record_class.create!(search_record_attributes) end end def update_in_search_index if searchable? search_record_class.upsert!(search_record_attributes) else remove_from_search_index end end def remove_from_search_index search_record_class.find_by(searchable_type: self.class.name, searchable_id: id)&.destroy end def search_record_attributes { account_id: account_id, searchable_type: self.class.name, searchable_id: id, card_id: search_card_id, board_id: search_board_id, title: search_title, content: search_record_content, created_at: created_at } end def search_record_content search_content&.truncate_bytes(SEARCH_CONTENT_LIMIT, omission: "") end def search_record_class Search::Record.for(account_id) end # Models must implement these methods: # - account_id: returns the account id # - search_title: returns title string or nil # - search_content: returns content string # - search_card_id: returns the card id (self.id for cards, card_id for comments) # - search_board_id: returns the board id # - searchable?: returns whether this record should be indexed end