inventory_refresh 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +0 -1
  3. data/.travis.yml +6 -8
  4. data/inventory_refresh.gemspec +2 -4
  5. data/lib/inventory_refresh.rb +0 -2
  6. data/lib/inventory_refresh/application_record_iterator.rb +9 -26
  7. data/lib/inventory_refresh/exception.rb +8 -0
  8. data/lib/inventory_refresh/inventory_collection.rb +36 -110
  9. data/lib/inventory_refresh/inventory_collection/builder.rb +6 -6
  10. data/lib/inventory_refresh/inventory_collection/data_storage.rb +0 -9
  11. data/lib/inventory_refresh/inventory_collection/helpers/initialize_helper.rb +34 -143
  12. data/lib/inventory_refresh/inventory_collection/helpers/questions_helper.rb +1 -44
  13. data/lib/inventory_refresh/inventory_collection/index/proxy.rb +6 -34
  14. data/lib/inventory_refresh/inventory_collection/index/type/base.rb +0 -8
  15. data/lib/inventory_refresh/inventory_collection/references_storage.rb +0 -17
  16. data/lib/inventory_refresh/inventory_collection/scanner.rb +1 -87
  17. data/lib/inventory_refresh/inventory_collection/serialization.rb +10 -16
  18. data/lib/inventory_refresh/inventory_object.rb +34 -68
  19. data/lib/inventory_refresh/inventory_object_lazy.rb +10 -17
  20. data/lib/inventory_refresh/persister.rb +63 -29
  21. data/lib/inventory_refresh/save_collection/base.rb +2 -4
  22. data/lib/inventory_refresh/save_collection/saver/base.rb +8 -108
  23. data/lib/inventory_refresh/save_collection/saver/concurrent_safe_batch.rb +48 -126
  24. data/lib/inventory_refresh/save_collection/saver/partial_upsert_helper.rb +19 -1
  25. data/lib/inventory_refresh/save_collection/saver/retention_helper.rb +3 -68
  26. data/lib/inventory_refresh/save_collection/saver/sql_helper.rb +0 -125
  27. data/lib/inventory_refresh/save_collection/saver/sql_helper_update.rb +5 -9
  28. data/lib/inventory_refresh/save_collection/saver/sql_helper_upsert.rb +9 -17
  29. data/lib/inventory_refresh/save_collection/sweeper.rb +91 -18
  30. data/lib/inventory_refresh/save_collection/topological_sort.rb +5 -5
  31. data/lib/inventory_refresh/save_inventory.rb +12 -5
  32. data/lib/inventory_refresh/version.rb +1 -1
  33. metadata +9 -45
  34. data/lib/inventory_refresh/save_collection/saver/batch.rb +0 -17
  35. data/lib/inventory_refresh/save_collection/saver/default.rb +0 -57
  36. data/lib/inventory_refresh/target.rb +0 -73
  37. data/lib/inventory_refresh/target_collection.rb +0 -92
@@ -50,11 +50,6 @@ module InventoryRefresh
50
50
  dependencies.all?(&:saved?)
51
51
  end
52
52
 
53
- # @return [Boolean] true if we are using a saver strategy that allows saving in parallel processes
54
- def parallel_safe?
55
- @parallel_safe_cache ||= %i(concurrent_safe concurrent_safe_batch).include?(saver_strategy)
56
- end
57
-
58
53
  # @return [Boolean] true if the model_class supports STI
59
54
  def supports_sti?
60
55
  @supports_sti_cache = model_class.column_names.include?("type") if @supports_sti_cache.nil?
@@ -81,50 +76,12 @@ module InventoryRefresh
81
76
  data_collection_finalized
82
77
  end
83
78
 
84
- # @return [Boolean] true is processing of this InventoryCollection will be in targeted mode
85
- def targeted?
86
- targeted
87
- end
88
-
89
79
  # True if processing of this InventoryCollection object would lead to no operations. Then we use this marker to
90
80
  # stop processing of the InventoryCollector object very soon, to avoid a lot of unnecessary Db queries, etc.
91
81
  #
92
82
  # @return [Boolean] true if processing of this InventoryCollection object would lead to no operations.
93
83
  def noop?
94
- # If this InventoryCollection doesn't do anything. it can easily happen for targeted/batched strategies.
95
- saving_noop? && delete_complement_noop?
96
- end
97
-
98
- # @return [Boolean] true if processing InventoryCollection will not lead to any created/updated/deleted record
99
- def saving_noop?
100
- saving_targeted_parent_collection_noop? || saving_targeted_child_collection_noop? || saving_full_collection_noop?
101
- end
102
-
103
- # @return true if processing InventoryCollection will not lead to deleting the complement of passed ids
104
- def delete_complement_noop?
105
- all_manager_uuids.nil?
106
- end
107
-
108
- private
109
-
110
- # @return true if it's a noop parent targeted InventoryCollection
111
- def saving_targeted_parent_collection_noop?
112
- targeted_noop_condition && parent_inventory_collections.blank? && targeted_scope.primary_references.blank?
113
- end
114
-
115
- # @return true if it's a noop child targeted InventoryCollection
116
- def saving_targeted_child_collection_noop?
117
- targeted_noop_condition && parent_inventory_collections.present? &&
118
- parent_inventory_collections.all? { |x| x.targeted_scope.primary_references.blank? }
119
- end
120
-
121
- # @return true if it's a noop full InventoryCollection refresh
122
- def saving_full_collection_noop?
123
- !targeted? && data.blank? && !delete_allowed? && skeletal_primary_index.blank?
124
- end
125
-
126
- def targeted_noop_condition
127
- targeted? && custom_save_block.nil? && skeletal_primary_index.blank?
84
+ data.blank? && custom_save_block.nil? && skeletal_primary_index.blank?
128
85
  end
129
86
  end
130
87
  end
@@ -64,14 +64,6 @@ module InventoryRefresh
64
64
  end
65
65
  end
66
66
 
67
- def reindex_secondary_indexes!
68
- data_indexes.each do |ref, index|
69
- next if ref == primary_index_ref
70
-
71
- index.reindex!
72
- end
73
- end
74
-
75
67
  def primary_index
76
68
  data_index(primary_index_ref)
77
69
  end
@@ -94,30 +86,16 @@ module InventoryRefresh
94
86
  end
95
87
  end
96
88
 
97
- def find_by(manager_uuid_hash, ref: primary_index_ref)
98
- # TODO(lsmola) deprecate this, it's enough to have find method
99
- find(manager_uuid_hash, :ref => ref)
100
- end
101
-
102
- def lazy_find_by(manager_uuid_hash, ref: primary_index_ref, key: nil, default: nil)
103
- # TODO(lsmola) deprecate this, it's enough to have lazy_find method
104
-
105
- lazy_find(manager_uuid_hash, :ref => ref, :key => key, :default => default)
106
- end
107
-
108
89
  def lazy_find(manager_uuid, ref: primary_index_ref, key: nil, default: nil, transform_nested_lazy_finds: false)
109
- # TODO(lsmola) also, it should be enough to have only 1 find method, everything can be lazy, until we try to
110
- # access the data
111
- # TODO(lsmola) lazy_find will support only hash, then we can remove the _by variant
112
90
  return if manager_uuid.nil?
113
91
  assert_index(manager_uuid, ref)
114
92
 
115
93
  ::InventoryRefresh::InventoryObjectLazy.new(inventory_collection,
116
- manager_uuid,
117
- :ref => ref,
118
- :key => key,
119
- :default => default,
120
- :transform_nested_lazy_finds => transform_nested_lazy_finds)
94
+ manager_uuid,
95
+ :ref => ref,
96
+ :key => key,
97
+ :default => default,
98
+ :transform_nested_lazy_finds => transform_nested_lazy_finds)
121
99
  end
122
100
 
123
101
  def named_ref(ref = primary_index_ref)
@@ -132,19 +110,13 @@ module InventoryRefresh
132
110
 
133
111
  delegate :association_to_foreign_key_mapping,
134
112
  :build_stringified_reference,
135
- :parallel_safe?,
136
113
  :strategy,
137
114
  :to => :inventory_collection
138
115
 
139
116
  attr_reader :all_refs, :data_indexes, :inventory_collection, :primary_ref, :local_db_indexes, :secondary_refs
140
117
 
141
118
  def find_in_data_or_skeletal_index(reference)
142
- if parallel_safe?
143
- # With parallel safe strategies, we create skeletal nodes that we can look for
144
- data_index_find(reference) || skeletal_index_find(reference)
145
- else
146
- data_index_find(reference)
147
- end
119
+ data_index_find(reference) || skeletal_index_find(reference)
148
120
  end
149
121
 
150
122
  def skeletal_index_find(reference)
@@ -27,14 +27,6 @@ module InventoryRefresh
27
27
  index[build_stringified_reference(inventory_object.data, attribute_names)] = inventory_object
28
28
  end
29
29
 
30
- # Rebuilds the indexes for all InventoryObject objects
31
- def reindex!
32
- self.index = {}
33
- data.each do |inventory_object|
34
- store_index_for(inventory_object)
35
- end
36
- end
37
-
38
30
  # @return [Array] Returns index data
39
31
  def index_data
40
32
  index.values
@@ -45,23 +45,6 @@ module InventoryRefresh
45
45
  add_reference(reference_data)
46
46
  end
47
47
 
48
- # Adds array of references to the storage. The reference can be already existing, otherwise we attempt to build
49
- # it.
50
- #
51
- # @param references_array [Array] Array of reference objects acceptable by add_reference method.
52
- # @param ref [Symbol] A key to specific reference, if it's a reference pointing to something else than primary
53
- # index.
54
- # @return [InventoryRefresh::InventoryCollection::ReferencesStorage] Returns self
55
- def merge!(references_array, ref: nil)
56
- references_array.each { |reference_data| add_reference(reference_data, :ref => ref) }
57
- self
58
- end
59
-
60
- # @return [Hash{String => InventoryRefresh::InventoryCollection::Reference}] Hash of indexed Reference objects
61
- def primary_references
62
- references[primary_index_ref]
63
- end
64
-
65
48
  # Builds a Reference object
66
49
  #
67
50
  # @param reference_data [InventoryRefresh::InventoryCollection::References, Hash, Object] Either existing Reference
@@ -41,7 +41,6 @@ module InventoryRefresh
41
41
  # Boolean helpers the scanner uses from the :inventory_collection
42
42
  delegate :inventory_object_lazy?,
43
43
  :inventory_object?,
44
- :targeted?,
45
44
  :to => :inventory_collection
46
45
 
47
46
  # Methods the scanner uses from the :inventory_collection
@@ -52,18 +51,13 @@ module InventoryRefresh
52
51
  :to => :inventory_collection
53
52
 
54
53
  # The data scanner modifies inside of the :inventory_collection
55
- delegate :all_manager_uuids_scope,
56
- :association,
54
+ delegate :association,
57
55
  :arel,
58
56
  :attribute_references,
59
57
  :custom_save_block,
60
58
  :data_collection_finalized=,
61
59
  :dependency_attributes,
62
- :targeted?,
63
- :targeted_scope,
64
60
  :parent,
65
- :parent_inventory_collections,
66
- :parent_inventory_collections=,
67
61
  :references,
68
62
  :transitive_dependency_attributes,
69
63
  :to => :inventory_collection
@@ -78,11 +72,6 @@ module InventoryRefresh
78
72
  # Scan InventoryCollection InventoryObjects and store the results inside of the InventoryCollection
79
73
  data.each do |inventory_object|
80
74
  scan_inventory_object!(inventory_object)
81
-
82
- if targeted? && parent_inventory_collections.blank?
83
- # We want to track what manager_uuids we should query from a db, for the targeted refresh
84
- targeted_scope << inventory_object.reference
85
- end
86
75
  end
87
76
 
88
77
  # Scan InventoryCollection skeletal data
@@ -90,80 +79,12 @@ module InventoryRefresh
90
79
  scan_inventory_object!(inventory_object)
91
80
  end
92
81
 
93
- build_parent_inventory_collections!
94
- scan_all_manager_uuids_scope!
95
-
96
82
  # Mark InventoryCollection as finalized aka. scanned
97
83
  self.data_collection_finalized = true
98
84
  end
99
85
 
100
86
  private
101
87
 
102
- def scan_all_manager_uuids_scope!
103
- return if all_manager_uuids_scope.nil?
104
-
105
- all_manager_uuids_scope.each do |scope|
106
- scope.each_value do |value|
107
- scan_all_manager_uuids_scope_attribute!(value)
108
- end
109
- end
110
- end
111
-
112
- def build_parent_inventory_collections!
113
- if parent_inventory_collections.nil?
114
- build_parent_inventory_collection!
115
- else
116
- # We can't figure out what immediate parent is, we'll add parent_inventory_collections as dependencies
117
- parent_inventory_collections.each { |ic_name| add_parent_inventory_collection_dependency!(ic_name) }
118
- end
119
-
120
- return if parent_inventory_collections.blank?
121
-
122
- # Transform InventoryCollection object names to actual objects
123
- self.parent_inventory_collections = parent_inventory_collections.map { |x| load_inventory_collection_by_name(x) }
124
- end
125
-
126
- def build_parent_inventory_collection!
127
- return unless supports_building_inventory_collection?
128
-
129
- if association.present? && parent.present? && associations_hash[association].present?
130
- # Add immediate parent IC as dependency
131
- add_parent_inventory_collection_dependency!(associations_hash[association])
132
- # Add root IC in parent_inventory_collections
133
- self.parent_inventory_collections = [find_parent_inventory_collection(associations_hash, inventory_collection.association)]
134
- end
135
- end
136
-
137
- def supports_building_inventory_collection?
138
- # Don't try to introspect ICs with custom query or saving code
139
- return if arel.present? || custom_save_block.present?
140
- # We support :parent_inventory_collections only for targeted mode, where all ICs are present
141
- return unless targeted?
142
-
143
- true
144
- end
145
-
146
- def add_parent_inventory_collection_dependency!(ic_name)
147
- ic = load_inventory_collection_by_name(ic_name)
148
- (dependency_attributes[:__parent_inventory_collections] ||= Set.new) << ic if ic
149
- end
150
-
151
- def find_parent_inventory_collection(hash, name)
152
- if hash[name]
153
- find_parent_inventory_collection(hash, hash[name])
154
- else
155
- name
156
- end
157
- end
158
-
159
- def load_inventory_collection_by_name(name)
160
- ic = indexed_inventory_collections[name]
161
- if ic.nil?
162
- raise "Can't find InventoryCollection :#{name} referenced from #{inventory_collection}" if targeted?
163
- end
164
- ic
165
- end
166
-
167
88
  def scan_inventory_object!(inventory_object)
168
89
  inventory_object.data.each do |key, value|
169
90
  if value.kind_of?(Array)
@@ -182,13 +103,6 @@ module InventoryRefresh
182
103
  value_inventory_collection.add_reference(value.reference, :key => value.key)
183
104
  end
184
105
 
185
- def scan_all_manager_uuids_scope_attribute!(value)
186
- return unless loadable?(value)
187
-
188
- add_reference(value.inventory_collection, value)
189
- (dependency_attributes[:__all_manager_uuids_scope] ||= Set.new) << value.inventory_collection
190
- end
191
-
192
106
  def scan_inventory_object_attribute!(key, value)
193
107
  return unless loadable?(value)
194
108
  value_inventory_collection = value.inventory_collection
@@ -3,10 +3,7 @@ require "active_support/core_ext/module/delegation"
3
3
  module InventoryRefresh
4
4
  class InventoryCollection
5
5
  class Serialization
6
- delegate :all_manager_uuids,
7
- :all_manager_uuids=,
8
- :build,
9
- :targeted_scope,
6
+ delegate :build,
10
7
  :data,
11
8
  :inventory_object_lazy?,
12
9
  :inventory_object?,
@@ -28,8 +25,6 @@ module InventoryRefresh
28
25
  # @param available_inventory_collections [Array<InventoryRefresh::InventoryCollection>] List of available
29
26
  # InventoryCollection objects
30
27
  def from_hash(inventory_objects_data, available_inventory_collections)
31
- targeted_scope.merge!(inventory_objects_data["manager_uuids"].map(&:symbolize_keys!)) if inventory_objects_data["manager_uuids"]
32
-
33
28
  (inventory_objects_data['data'] || []).each do |inventory_object_data|
34
29
  build(hash_to_data(inventory_object_data, available_inventory_collections).symbolize_keys!)
35
30
  end
@@ -37,8 +32,12 @@ module InventoryRefresh
37
32
  (inventory_objects_data['partial_data'] || []).each do |inventory_object_data|
38
33
  skeletal_primary_index.build(hash_to_data(inventory_object_data, available_inventory_collections).symbolize_keys!)
39
34
  end
35
+ end
40
36
 
41
- self.all_manager_uuids = inventory_objects_data['all_manager_uuids']
37
+ def sweep_scope_from_hash(sweep_scope, available_inventory_collections)
38
+ sweep_scope.map do |s|
39
+ hash_to_data(s, available_inventory_collections).symbolize_keys!
40
+ end
42
41
  end
43
42
 
44
43
  # Serializes InventoryCollection's data storage into Array of Hashes
@@ -47,14 +46,15 @@ module InventoryRefresh
47
46
  def to_hash
48
47
  {
49
48
  :name => name,
50
- # TODO(lsmola) we do not support nested references here, should we?
51
- :manager_uuids => targeted_scope.primary_references.values.map(&:full_reference),
52
- :all_manager_uuids => all_manager_uuids,
53
49
  :data => data.map { |x| data_to_hash(x.data) },
54
50
  :partial_data => skeletal_primary_index.index_data.map { |x| data_to_hash(x.data) },
55
51
  }
56
52
  end
57
53
 
54
+ def sweep_scope_to_hash(sweep_scope)
55
+ sweep_scope.map { |x| data_to_hash(x) }
56
+ end
57
+
58
58
  private
59
59
 
60
60
  # Converts InventoryRefresh::InventoryObject or InventoryRefresh::InventoryObjectLazy into Hash
@@ -107,10 +107,6 @@ module InventoryRefresh
107
107
  hash.transform_values do |value|
108
108
  if value.kind_of?(Hash) && value['inventory_collection_name']
109
109
  hash_to_lazy_relation(value, available_inventory_collections, depth)
110
- elsif value.kind_of?(Array) && value.first.kind_of?(Hash) && value.first['inventory_collection_name']
111
- # TODO(lsmola) do we need to compact it sooner? What if first element is nil? On the other hand, we want to
112
- # deprecate this Vm HABTM assignment because it's not effective
113
- value.compact.map { |x| hash_to_lazy_relation(x, available_inventory_collections, depth) }
114
110
  else
115
111
  value
116
112
  end
@@ -128,8 +124,6 @@ module InventoryRefresh
128
124
  data.transform_values do |value|
129
125
  if inventory_object_lazy?(value) || inventory_object?(value)
130
126
  lazy_relation_to_hash(value, depth)
131
- elsif value.kind_of?(Array) && (inventory_object_lazy?(value.compact.first) || inventory_object?(value.compact.first))
132
- value.compact.map { |x| lazy_relation_to_hash(x, depth) }
133
127
  else
134
128
  value
135
129
  end
@@ -42,64 +42,12 @@ module InventoryRefresh
42
42
  # Transforms InventoryObject object data into hash format with keys that are column names and resolves correct
43
43
  # values of the foreign keys (even the polymorphic ones)
44
44
  #
45
- # @param inventory_collection_scope [InventoryRefresh::InventoryCollection] parent InventoryCollection object
46
- # @return [Hash] Data in DB format
47
- def attributes(inventory_collection_scope = nil)
48
- # We should explicitly pass a scope, since the inventory_object can be mapped to more InventoryCollections with
49
- # different blacklist and whitelist. The generic code always passes a scope.
50
- inventory_collection_scope ||= inventory_collection
51
-
52
- attributes_for_saving = {}
53
- # First transform the values
54
- data.each do |key, value|
55
- if !allowed?(inventory_collection_scope, key)
56
- next
57
- elsif value.kind_of?(Array) && value.any? { |x| loadable?(x) }
58
- # Lets fill also the original data, so other InventoryObject referring to this attribute gets the right
59
- # result
60
- data[key] = value.compact.map(&:load).compact
61
- # We can use built in _ids methods to assign array of ids into has_many relations. So e.g. the :key_pairs=
62
- # relation setter will become :key_pair_ids=
63
- attributes_for_saving[(key.to_s.singularize + "_ids").to_sym] = data[key].map(&:id).compact.uniq
64
- elsif loadable?(value) || inventory_collection_scope.association_to_foreign_key_mapping[key]
65
- # Lets fill also the original data, so other InventoryObject referring to this attribute gets the right
66
- # result
67
- data[key] = value.load if value.respond_to?(:load)
68
- if (foreign_key = inventory_collection_scope.association_to_foreign_key_mapping[key])
69
- # We have an association to fill, lets fill also the :key, cause some other InventoryObject can refer to it
70
- record_id = data[key].try(:id)
71
- attributes_for_saving[foreign_key.to_sym] = record_id
72
-
73
- if (foreign_type = inventory_collection_scope.association_to_foreign_type_mapping[key])
74
- # If we have a polymorphic association, we need to also fill a base class name, but we want to nullify it
75
- # if record_id is missing
76
- base_class = data[key].try(:base_class_name) || data[key].class.try(:base_class).try(:name)
77
- attributes_for_saving[foreign_type.to_sym] = record_id ? base_class : nil
78
- end
79
- elsif data[key].kind_of?(::InventoryRefresh::InventoryObject)
80
- # We have an association to fill but not an Activerecord association, so e.g. Ancestry, lets just load
81
- # it here. This way of storing ancestry is ineffective in DB call count, but RAM friendly
82
- attributes_for_saving[key.to_sym] = data[key].base_class_name.constantize.find_by(:id => data[key].id)
83
- else
84
- # We have a normal attribute to fill
85
- attributes_for_saving[key.to_sym] = data[key]
86
- end
87
- else
88
- attributes_for_saving[key.to_sym] = value
89
- end
90
- end
91
-
92
- attributes_for_saving
93
- end
94
-
95
- # Transforms InventoryObject object data into hash format with keys that are column names and resolves correct
96
- # values of the foreign keys (even the polymorphic ones)
97
- #
45
+ # @param data [Array<Object>] Array of objects that we want to map to DB table columns
98
46
  # @param inventory_collection_scope [InventoryRefresh::InventoryCollection] parent InventoryCollection object
99
47
  # @param all_attribute_keys [Array<Symbol>] Attribute keys we will modify based on object's data
100
48
  # @param inventory_object [InventoryRefresh::InventoryObject] InventoryObject object owning these attributes
101
49
  # @return [Hash] Data in DB format
102
- def attributes_with_keys(inventory_collection_scope = nil, all_attribute_keys = [], inventory_object = nil)
50
+ def self.attributes_with_keys(data, inventory_collection_scope = nil, all_attribute_keys = [], inventory_object = nil)
103
51
  # We should explicitly pass a scope, since the inventory_object can be mapped to more InventoryCollections with
104
52
  # different blacklist and whitelist. The generic code always passes a scope.
105
53
  inventory_collection_scope ||= inventory_collection
@@ -206,6 +154,36 @@ module InventoryRefresh
206
154
  end
207
155
  end
208
156
 
157
+ # Return true if the attribute is allowed to be saved into the DB
158
+ #
159
+ # @param inventory_collection_scope [InventoryRefresh::InventoryCollection] InventoryCollection object owning the
160
+ # attribute
161
+ # @param key [Symbol] attribute name
162
+ # @return true if the attribute is allowed to be saved into the DB
163
+ def self.allowed?(inventory_collection_scope, key)
164
+ foreign_to_association = (inventory_collection_scope.foreign_key_to_association_mapping[key] ||
165
+ inventory_collection_scope.foreign_type_to_association_mapping[key])
166
+
167
+ return false if inventory_collection_scope.attributes_blacklist.present? &&
168
+ (inventory_collection_scope.attributes_blacklist.include?(key) ||
169
+ (foreign_to_association && inventory_collection_scope.attributes_blacklist.include?(foreign_to_association)))
170
+
171
+ return false if inventory_collection_scope.attributes_whitelist.present? &&
172
+ (!inventory_collection_scope.attributes_whitelist.include?(key) &&
173
+ (!foreign_to_association || (foreign_to_association && inventory_collection_scope.attributes_whitelist.include?(foreign_to_association))))
174
+
175
+ true
176
+ end
177
+
178
+ # Return true if the object is loadable, which we determine by a list of loadable classes.
179
+ #
180
+ # @param value [Object] object we test
181
+ # @return true if the object is loadable
182
+ def self.loadable?(value)
183
+ value.kind_of?(::InventoryRefresh::InventoryObjectLazy) || value.kind_of?(::InventoryRefresh::InventoryObject) ||
184
+ value.kind_of?(::InventoryRefresh::ApplicationRecordReference)
185
+ end
186
+
209
187
  private
210
188
 
211
189
  # Assigns value based on the version attributes. If versions are specified, it asigns attribute only if it's
@@ -283,18 +261,7 @@ module InventoryRefresh
283
261
  # @param key [Symbol] attribute name
284
262
  # @return true if the attribute is allowed to be saved into the DB
285
263
  def allowed?(inventory_collection_scope, key)
286
- foreign_to_association = inventory_collection_scope.foreign_key_to_association_mapping[key] ||
287
- inventory_collection_scope.foreign_type_to_association_mapping[key]
288
-
289
- return false if inventory_collection_scope.attributes_blacklist.present? &&
290
- (inventory_collection_scope.attributes_blacklist.include?(key) ||
291
- (foreign_to_association && inventory_collection_scope.attributes_blacklist.include?(foreign_to_association)))
292
-
293
- return false if inventory_collection_scope.attributes_whitelist.present? &&
294
- (!inventory_collection_scope.attributes_whitelist.include?(key) &&
295
- (!foreign_to_association || (foreign_to_association && inventory_collection_scope.attributes_whitelist.include?(foreign_to_association))))
296
-
297
- true
264
+ self.class.allowed?(inventory_collection_scope, key)
298
265
  end
299
266
 
300
267
  # Return true if the object is loadable, which we determine by a list of loadable classes.
@@ -302,8 +269,7 @@ module InventoryRefresh
302
269
  # @param value [Object] object we test
303
270
  # @return true if the object is loadable
304
271
  def loadable?(value)
305
- value.kind_of?(::InventoryRefresh::InventoryObjectLazy) || value.kind_of?(::InventoryRefresh::InventoryObject) ||
306
- value.kind_of?(::InventoryRefresh::ApplicationRecordReference)
272
+ self.class.loadable?(value)
307
273
  end
308
274
  end
309
275
  end