Class: Chewy::Index::Adapter::Orm

Inherits:
Base
  • Object
show all
Defined in:
lib/chewy/index/adapter/orm.rb

Direct Known Subclasses

ActiveRecord

Constant Summary

Constants inherited from Base

Base::BATCH_SIZE

Instance Attribute Summary collapse

Attributes inherited from Base

#options, #target

Instance Method Summary collapse

Methods inherited from Base

accepts?, #type_name

Constructor Details

#initialize(target, **options) ⇒ Orm

Returns a new instance of Orm.



9
10
11
12
13
14
15
16
17
18
19
# File 'lib/chewy/index/adapter/orm.rb', line 9

def initialize(target, **options)
  if target.is_a?(relation_class)
    @target = model_of_relation(target)
    @default_scope = target
  else
    @target = target
    @default_scope = all_scope
  end
  @options = options
  cleanup_default_scope!
end

Instance Attribute Details

#default_scopeObject (readonly)

Returns the value of attribute default_scope.



7
8
9
# File 'lib/chewy/index/adapter/orm.rb', line 7

def default_scope
  @default_scope
end

Instance Method Details

#identify(collection) ⇒ Object



25
26
27
28
29
30
31
32
33
# File 'lib/chewy/index/adapter/orm.rb', line 25

def identify(collection)
  if collection.is_a?(relation_class)
    pluck(collection)
  else
    Array.wrap(collection).map do |entity|
      entity.respond_to?(primary_key) ? entity.public_send(primary_key) : entity
    end
  end
end

#import(*args, &block) ⇒ Object

Import method for ORM takes import data and import options

Import data types:

* Nothing passed - imports all the model data according to type
  default scope
* ORM scope
* Objects collection
* Ids collection

Import options:

<tt>:batch_size</tt> - import batch size, 1000 objects by default
<tt>:direct_import</tt> - import objects without reloading

Method handles destroyed objects as well. In case of objects ORM scope or array passed, objects, responding with true to ‘destroyed?` method will be deleted from index. In case of ids array passed - documents with missing source object ids will be deleted from index:

users = User.all
users.each { |user| user.destroy if user.inactive? }
UsersIndex.import users # inactive users will be deleted from index
# or
UsersIndex.import users.map(&:id) # deleted user ids will be deleted from index

Also there is custom type option ‘delete_if`. It it returns `true` object will be deleted from index. Note that if this option is defined and return `false` Chewy will still check `destroyed?` method. This is useful for paranoid objects deleting implementation.

index_scope User, delete_if: ->{ deleted_at }
...

users = User.all
users.each { |user| user.deleted_at = Time.now }
UsersIndex.import users # paranoid deleted users will be deleted from index
# or
UsersIndex.import users.map(&:id) # user ids will be deleted from index


75
76
77
78
79
80
81
82
83
# File 'lib/chewy/index/adapter/orm.rb', line 75

def import(*args, &block)
  collection, options = import_args(*args)

  if !collection.is_a?(relation_class) || options[:direct_import]
    import_objects(collection, options, &block)
  else
    import_scope(collection, options, &block)
  end
end

#import_fields(*args, &block) ⇒ Object Also known as: import_references



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/chewy/index/adapter/orm.rb', line 85

def import_fields(*args, &block)
  return enum_for(:import_fields, *args) unless block_given?

  collection, options = import_args(*args)

  if options[:fields].present? || collection.is_a?(relation_class)
    collection = all_scope_where_ids_in(identify(collection)) unless collection.is_a?(relation_class)
    pluck_in_batches(collection, **options.slice(:fields, :batch_size, :typecast), &block)
  else
    identify(collection).each_slice(options[:batch_size], &block)
  end
end

#load(ids, **options) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/chewy/index/adapter/orm.rb', line 99

def load(ids, **options)
  scope = all_scope_where_ids_in(ids)
  additional_scope = options[options[:_index].to_sym].try(:[], :scope) || options[:scope]

  loaded_objects = load_scope_objects(scope, additional_scope)
  loaded_objects = raw(loaded_objects, options[:raw_import]) if options[:raw_import]

  indexed_objects = loaded_objects.index_by do |object|
    object.public_send(primary_key).to_s
  end

  ids.map { |id| indexed_objects[id.to_s] }
end

#nameObject



21
22
23
# File 'lib/chewy/index/adapter/orm.rb', line 21

def name
  @name ||= (options[:name].presence || target.name).to_s.camelize.demodulize
end