diff options
Diffstat (limited to 'app/models/concerns/analytics/cycle_analytics')
-rw-r--r-- | app/models/concerns/analytics/cycle_analytics/parentable.rb | 22 | ||||
-rw-r--r-- | app/models/concerns/analytics/cycle_analytics/stageable.rb (renamed from app/models/concerns/analytics/cycle_analytics/stage.rb) | 68 |
2 files changed, 53 insertions, 37 deletions
diff --git a/app/models/concerns/analytics/cycle_analytics/parentable.rb b/app/models/concerns/analytics/cycle_analytics/parentable.rb new file mode 100644 index 00000000000..785f6eea6bf --- /dev/null +++ b/app/models/concerns/analytics/cycle_analytics/parentable.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Analytics + module CycleAnalytics + module Parentable + extend ActiveSupport::Concern + + included do + belongs_to :namespace, class_name: 'Namespace', foreign_key: :group_id, optional: false # rubocop: disable Rails/InverseOf + + validate :ensure_namespace_type + + def ensure_namespace_type + return if namespace.nil? + return if namespace.is_a?(::Namespaces::ProjectNamespace) || namespace.is_a?(::Group) + + errors.add(:namespace, s_('CycleAnalytics|the assigned object is not supported')) + end + end + end + end +end diff --git a/app/models/concerns/analytics/cycle_analytics/stage.rb b/app/models/concerns/analytics/cycle_analytics/stageable.rb index d9e6756ab86..d1f948d1366 100644 --- a/app/models/concerns/analytics/cycle_analytics/stage.rb +++ b/app/models/concerns/analytics/cycle_analytics/stageable.rb @@ -2,7 +2,7 @@ module Analytics module CycleAnalytics - module Stage + module Stageable extend ActiveSupport::Concern include RelativePositioning include Gitlab::Utils::StrongMemoize @@ -10,7 +10,7 @@ module Analytics included do belongs_to :start_event_label, class_name: 'GroupLabel', optional: true belongs_to :end_event_label, class_name: 'GroupLabel', optional: true - belongs_to :stage_event_hash, class_name: 'Analytics::CycleAnalytics::StageEventHash', foreign_key: :stage_event_hash_id, optional: true + belongs_to :stage_event_hash, class_name: 'Analytics::CycleAnalytics::StageEventHash', optional: true validates :name, presence: true validates :name, exclusion: { in: Gitlab::Analytics::CycleAnalytics::DefaultStages.names }, if: :custom? @@ -21,39 +21,31 @@ module Analytics validate :validate_stage_event_pairs validate :validate_labels - enum start_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :start_event_identifier - enum end_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :end_event_identifier + enum start_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, + _prefix: :start_event_identifier + enum end_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, + _prefix: :end_event_identifier alias_attribute :custom_stage?, :custom scope :default_stages, -> { where(custom: false) } scope :ordered, -> { order(:relative_position, :id) } scope :with_preloaded_labels, -> { includes(:start_event_label, :end_event_label) } scope :for_list, -> { with_preloaded_labels.ordered } - scope :by_value_stream, -> (value_stream) { where(value_stream_id: value_stream.id) } + scope :by_value_stream, ->(value_stream) { where(value_stream_id: value_stream.id) } before_save :ensure_stage_event_hash_id after_commit :cleanup_old_stage_event_hash end - def parent=(_) - raise NotImplementedError - end - - def parent - raise NotImplementedError - end - def start_event - strong_memoize(:start_event) do - Gitlab::Analytics::CycleAnalytics::StageEvents[start_event_identifier].new(params_for_start_event) - end + Gitlab::Analytics::CycleAnalytics::StageEvents[start_event_identifier].new(params_for_start_event) end + strong_memoize_attr :start_event def end_event - strong_memoize(:end_event) do - Gitlab::Analytics::CycleAnalytics::StageEvents[end_event_identifier].new(params_for_end_event) - end + Gitlab::Analytics::CycleAnalytics::StageEvents[end_event_identifier].new(params_for_end_event) end + strong_memoize_attr :end_event def events_hash_code Digest::SHA256.hexdigest("#{start_event.hash_code}-#{end_event.hash_code}") @@ -109,9 +101,9 @@ module Analytics def validate_stage_event_pairs return if start_event_identifier.nil? || end_event_identifier.nil? - unless pairing_rules.fetch(start_event.class, []).include?(end_event.class) - errors.add(:end_event, s_('CycleAnalytics|not allowed for the given start event')) - end + return if pairing_rules.fetch(start_event.class, []).include?(end_event.class) + + errors.add(:end_event, s_('CycleAnalytics|not allowed for the given start event')) end def pairing_rules @@ -119,21 +111,23 @@ module Analytics end def validate_labels - validate_label_within_group(:start_event_label_id, start_event_label_id) if start_event_label_id_changed? - validate_label_within_group(:end_event_label_id, end_event_label_id) if end_event_label_id_changed? + validate_label_within_namespace(:start_event_label_id, start_event_label_id) if start_event_label_id_changed? + validate_label_within_namespace(:end_event_label_id, end_event_label_id) if end_event_label_id_changed? end - def validate_label_within_group(association_name, label_id) + def validate_label_within_namespace(association_name, label_id) return unless label_id - return unless group - unless label_available_for_group?(label_id) - errors.add(association_name, s_('CycleAnalyticsStage|is not available for the selected group')) - end + return if label_available_for_namespace?(label_id) + + errors.add(association_name, s_('CycleAnalyticsStage|is not available for the selected group')) end - def label_available_for_group?(label_id) - LabelsFinder.new(nil, { group_id: group.id, include_ancestor_groups: true, only_group_labels: true }) + def label_available_for_namespace?(label_id) + subject = is_a?(::Analytics::CycleAnalytics::Stage) ? namespace : project.group + return unless subject + + LabelsFinder.new(nil, { group_id: subject.id, include_ancestor_groups: true, only_group_labels: true }) .execute(skip_authorization: true) .id_in(label_id) .exists? @@ -142,15 +136,15 @@ module Analytics def ensure_stage_event_hash_id previous_stage_event_hash = stage_event_hash&.hash_sha256 - if previous_stage_event_hash.blank? || events_hash_code != previous_stage_event_hash - self.stage_event_hash_id = Analytics::CycleAnalytics::StageEventHash.record_id_by_hash_sha256(events_hash_code) - end + return unless previous_stage_event_hash.blank? || events_hash_code != previous_stage_event_hash + + self.stage_event_hash_id = Analytics::CycleAnalytics::StageEventHash.record_id_by_hash_sha256(events_hash_code) end def cleanup_old_stage_event_hash - if stage_event_hash_id_previously_changed? && stage_event_hash_id_previously_was - Analytics::CycleAnalytics::StageEventHash.cleanup_if_unused(stage_event_hash_id_previously_was) - end + return unless stage_event_hash_id_previously_changed? && stage_event_hash_id_previously_was + + Analytics::CycleAnalytics::StageEventHash.cleanup_if_unused(stage_event_hash_id_previously_was) end end end |