Project

General

Profile

Download (5.95 KB) Statistics
| Branch: | Tag: | Revision:
#
# Copyright 2014 Red Hat, Inc.
#
# This software is licensed to you under the GNU General Public
# License as published by the Free Software Foundation; either version
# 2 of the License (GPLv2) or (at your option) any later version.
# There is NO WARRANTY for this software, express or implied,
# including the implied warranties of MERCHANTABILITY,
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
# have received a copy of GPLv2 along with this software; if not, see
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.

module Katello
module Ext::IndexedModel

# TODO: move methods out into submodule
# rubocop:disable MethodLength
def self.included(base)
base.class_eval do

cattr_accessor :class_index_options

def self.display_attributes
self.class_index_options[:display_attrs].sort{|a, b| a.to_s <=> b.to_s}
end

if Rails.env.development? || Rails.env.production?
include Tire::Model::Search
include Tire::Model::Callbacks
index_name Katello.config.elastic_index + '_' + self.base_class.name.downcase

#Shared analyzers. If you need a model-specific analyzer for some reason,
# we'll need to refactor this to support that.
settings :analysis => {
:filter => Util::Search.custom_filters,
:analyzer => Util::Search.custom_analyzers
}

def self.index_import(list)
self.index.import(list)
end

after_save :refresh_index

else
#stub mapping
def self.mapping(*args)
{}
end
def self.index_import(list)
end
def self.index_name(name)
end
end

def disable_auto_reindex!
@disable_auto_reindex = true
end

def enable_auto_reindex!
@disable_auto_reindex = false
end

def refresh_index
return if @disable_auto_reindex
self.class.index.refresh if self.class.respond_to?(:index)
end

##
# :json - normal to_json options, :only or :except allowed
# :extended_json - function to call to return a hash to merge into document
# :display_attrs - list of attributes to display as searchable
##
def self.index_options(options = {})
self.class_index_options = options
end

# If this object (e.g. host_collection) is updated or deleted and another model (e.g. system) has an
# association (e.g. has_many) to it, we need to update the related indexes on that model (e.g system)
# relation - the association for the other model
# attribute - the attribute on the current model, which if changes needs to trigger the index update
def self.update_related_indexes(relation, attribute)
after_save lambda{|record| reindex_on_update(relation, attribute)}
before_destroy lambda{|record| save_indexed_relation(relation)}
after_destroy lambda{|record| reindex_relation}
end

# If this model (e.g. host_collection) has an association (e.g. has_many) to another model (e.g. system)
# and objects (e.g. systems) are added or removed for that association, we need to update the related
# indexes on that model.
def self.update_association_indexes
{ :after_add => :reindex_on_association_change, :after_remove => :reindex_on_association_change }
end

def reindex_on_association_change(record)
record.update_index if record.respond_to? :update_index
record.class.index.refresh if record.class.respond_to? :index
end

def reindex_on_update(relation, attribute)
return if @disable_auto_reindex
# If the specified attribute (e.g. name) on the current model has changed, update the related indexes
if self.send("#{attribute}_changed?")
related_objects = self.send(relation)
update_related_objects related_objects
end
end

def save_indexed_relation(relation)
# If an object (e.g. host_collection) is being deleted and another object (e.g. system) has a model
# relationship (e.g. has_many :through) with it, we need to update the indexes on that other model.
# Unfortunately, in order to do that, the update needs to be performed after this object is destroyed
# (i.e. after_destroy); however, at that point, the object (e.g. host_collection) no longer references
# the other (e.g. system).
#
# Temporarily save a list of the related objects that need indexes updated, for use in the 'after_destroy'.
@related_objects = self.send(relation)
end

def reindex_relation
update_related_objects @related_objects
end

def update_related_objects(objects)
unless objects.blank?
objects.each do |object|
object.update_index if object.respond_to? :update_index
end
end
end

def self.use_index_of(model)
if Rails.env.development? || Rails.env.production?
index_name model.index_name
document_type model.document_type
end
end
end
end

#mocked methods for testing
unless Rails.env.development? || Rails.env.production?
def update_index
end
end

def indexed_attributes
attrs = self.attributes.keys.collect{|key| key.to_sym}
attrs += self.lazy_attributes if self.respond_to?(:lazy_attributes)
if self.class.class_index_options[:json]
options = self.class.class_index_options[:json]
if options[:only]
attrs = options[:only]
elsif options[:except]
attrs -= options[:except]
end
end
attrs
end

def to_indexed_json
return {} if @disable_auto_reindex
to_ret = {}

attrs = self.indexed_attributes

(attrs).each do |attr|
to_ret[attr] = self.send(attr)
end

if self.class.class_index_options[:extended_json]
to_ret.merge!(self.send(self.class.class_index_options[:extended_json]))
end

to_ret.to_json
end

end
end
(1-1/2)