summaryrefslogtreecommitdiff
path: root/lib/gitlab/json_cache.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/json_cache.rb')
-rw-r--r--lib/gitlab/json_cache.rb31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/gitlab/json_cache.rb b/lib/gitlab/json_cache.rb
index 1adf83739ad..e4bc437d787 100644
--- a/lib/gitlab/json_cache.rb
+++ b/lib/gitlab/json_cache.rb
@@ -71,7 +71,36 @@ module Gitlab
end
def parse_entry(raw, klass)
- klass.new(raw) if valid_entry?(raw, klass)
+ return unless valid_entry?(raw, klass)
+ return klass.new(raw) unless klass.ancestors.include?(ActiveRecord::Base)
+
+ # When the cached value is a persisted instance of ActiveRecord::Base in
+ # some cases a relation can return an empty collection becauses scope.none!
+ # is being applied on ActiveRecord::Associations::CollectionAssociation#scope
+ # when the new_record? method incorrectly returns false.
+ #
+ # See https://gitlab.com/gitlab-org/gitlab-ee/issues/9903#note_145329964
+ klass
+ .allocate
+ .init_with(
+ "attributes" => attributes_for(klass, raw),
+ "new_record" => new_record?(raw, klass)
+ )
+ end
+
+ def attributes_for(klass, raw)
+ # We have models that leave out some fields from the JSON export for
+ # security reasons, e.g. models that include the CacheMarkdownField.
+ # The ActiveRecord::AttributeSet we build from raw does know about
+ # these columns so we need manually set them.
+ missing_attributes = (klass.columns.map(&:name) - raw.keys)
+ missing_attributes.each { |column| raw[column] = nil }
+
+ klass.attributes_builder.build_from_database(raw, {})
+ end
+
+ def new_record?(raw, klass)
+ raw.fetch(klass.primary_key, nil).blank?
end
def valid_entry?(raw, klass)