Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-19 21:08:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-19 21:08:11 +0300
commitd84f18d66c1fc46f244b0f4dec8bf65b90d9882a (patch)
tree2382ce0df6d7417e93afdf113a9fd15d7b46a653 /app/services/ci/update_instance_variables_service.rb
parentf2151c65d5826f0609a716e185893787b6375ae3 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services/ci/update_instance_variables_service.rb')
-rw-r--r--app/services/ci/update_instance_variables_service.rb72
1 files changed, 72 insertions, 0 deletions
diff --git a/app/services/ci/update_instance_variables_service.rb b/app/services/ci/update_instance_variables_service.rb
new file mode 100644
index 00000000000..ee513647d08
--- /dev/null
+++ b/app/services/ci/update_instance_variables_service.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+# This class is a simplified version of assign_nested_attributes_for_collection_association from ActiveRecord
+# https://github.com/rails/rails/blob/v6.0.2.1/activerecord/lib/active_record/nested_attributes.rb#L466
+
+module Ci
+ class UpdateInstanceVariablesService
+ UNASSIGNABLE_KEYS = %w(id _destroy).freeze
+
+ def initialize(params)
+ @params = params[:variables_attributes]
+ end
+
+ def execute
+ instantiate_records
+ persist_records
+ end
+
+ def errors
+ @records.to_a.flat_map { |r| r.errors.full_messages }
+ end
+
+ private
+
+ attr_reader :params
+
+ def existing_records_by_id
+ @existing_records_by_id ||= Ci::InstanceVariable
+ .all
+ .index_by { |var| var.id.to_s }
+ end
+
+ def instantiate_records
+ @records = params.map do |attributes|
+ find_or_initialize_record(attributes).tap do |record|
+ record.assign_attributes(attributes.except(*UNASSIGNABLE_KEYS))
+ record.mark_for_destruction if has_destroy_flag?(attributes)
+ end
+ end
+ end
+
+ def find_or_initialize_record(attributes)
+ id = attributes[:id].to_s
+
+ if id.blank?
+ Ci::InstanceVariable.new
+ else
+ existing_records_by_id.fetch(id) { raise ActiveRecord::RecordNotFound }
+ end
+ end
+
+ def persist_records
+ Ci::InstanceVariable.transaction do
+ success = @records.map do |record|
+ if record.marked_for_destruction?
+ record.destroy
+ else
+ record.save
+ end
+ end.all?
+
+ raise ActiveRecord::Rollback unless success
+
+ success
+ end
+ end
+
+ def has_destroy_flag?(hash)
+ Gitlab::Utils.to_boolean(hash['_destroy'])
+ end
+ end
+end