inventory_refresh 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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