diff options
Diffstat (limited to 'lib/gitlab/json_cache.rb')
-rw-r--r-- | lib/gitlab/json_cache.rb | 31 |
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) |