summaryrefslogtreecommitdiff
path: root/app/models/concerns
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/concerns')
-rw-r--r--app/models/concerns/internal_id.rb10
-rw-r--r--app/models/concerns/issuable.rb6
-rw-r--r--app/models/concerns/mentionable.rb4
-rw-r--r--app/models/concerns/milestoneish.rb2
-rw-r--r--app/models/concerns/statuseable.rb81
5 files changed, 93 insertions, 10 deletions
diff --git a/app/models/concerns/internal_id.rb b/app/models/concerns/internal_id.rb
index 51288094ef1..5382dde6765 100644
--- a/app/models/concerns/internal_id.rb
+++ b/app/models/concerns/internal_id.rb
@@ -7,11 +7,13 @@ module InternalId
end
def set_iid
- records = project.send(self.class.name.tableize)
- records = records.with_deleted if self.paranoid?
- max_iid = records.maximum(:iid)
+ if iid.blank?
+ records = project.send(self.class.name.tableize)
+ records = records.with_deleted if self.paranoid?
+ max_iid = records.maximum(:iid)
- self.iid = max_iid.to_i + 1
+ self.iid = max_iid.to_i + 1
+ end
end
def to_param
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 6af76c97cd3..9b77b88ca80 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -36,14 +36,14 @@ module Issuable
scope :only_opened, -> { with_state(:opened) }
scope :only_reopened, -> { with_state(:reopened) }
scope :closed, -> { with_state(:closed) }
- scope :order_milestone_due_desc, -> { joins(:milestone).reorder('milestones.due_date DESC, milestones.id DESC') }
- scope :order_milestone_due_asc, -> { joins(:milestone).reorder('milestones.due_date ASC, milestones.id ASC') }
- scope :with_label, ->(title) { joins(:labels).where(labels: { title: title }) }
+ scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') }
+ scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') }
scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
scope :join_project, -> { joins(:project) }
scope :references_project, -> { references(:project) }
scope :non_archived, -> { join_project.where(projects: { archived: false }) }
+ scope :outer_join_milestone, -> { joins("LEFT OUTER JOIN milestones ON milestones.id = #{table_name}.milestone_id") }
delegate :name,
:email,
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index 98f71ae8cb0..b381d225485 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -43,8 +43,8 @@ module Mentionable
self
end
- def all_references(current_user = self.author, text = nil)
- ext = Gitlab::ReferenceExtractor.new(self.project, current_user, self.author)
+ def all_references(current_user = nil, text = nil)
+ ext = Gitlab::ReferenceExtractor.new(self.project, current_user || self.author, self.author)
if text
ext.analyze(text)
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index 5b8e3f654ea..7bcc78247ba 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -8,7 +8,7 @@ module Milestoneish
end
def complete?(user = nil)
- total_items_count(user) == closed_items_count(user)
+ total_items_count(user) > 0 && total_items_count(user) == closed_items_count(user)
end
def percent_complete(user = nil)
diff --git a/app/models/concerns/statuseable.rb b/app/models/concerns/statuseable.rb
new file mode 100644
index 00000000000..3ef91caad47
--- /dev/null
+++ b/app/models/concerns/statuseable.rb
@@ -0,0 +1,81 @@
+module Statuseable
+ extend ActiveSupport::Concern
+
+ AVAILABLE_STATUSES = %w(pending running success failed canceled skipped)
+
+ class_methods do
+ def status_sql
+ builds = all.select('count(*)').to_sql
+ success = all.success.select('count(*)').to_sql
+ ignored = all.ignored.select('count(*)').to_sql if all.respond_to?(:ignored)
+ ignored ||= '0'
+ pending = all.pending.select('count(*)').to_sql
+ running = all.running.select('count(*)').to_sql
+ canceled = all.canceled.select('count(*)').to_sql
+ skipped = all.skipped.select('count(*)').to_sql
+
+ deduce_status = "(CASE
+ WHEN (#{builds})=0 THEN NULL
+ WHEN (#{builds})=(#{success})+(#{ignored}) THEN 'success'
+ WHEN (#{builds})=(#{pending}) THEN 'pending'
+ WHEN (#{builds})=(#{canceled})+(#{success})+(#{ignored}) THEN 'canceled'
+ WHEN (#{builds})=(#{skipped}) THEN 'skipped'
+ WHEN (#{running})+(#{pending})>0 THEN 'running'
+ ELSE 'failed'
+ END)"
+
+ deduce_status
+ end
+
+ def status
+ all.pluck(self.status_sql).first
+ end
+
+ def duration
+ duration_array = all.map(&:duration).compact
+ duration_array.reduce(:+)
+ end
+
+ def started_at
+ all.minimum(:started_at)
+ end
+
+ def finished_at
+ all.maximum(:finished_at)
+ end
+ end
+
+ included do
+ validates :status, inclusion: { in: AVAILABLE_STATUSES }
+
+ state_machine :status, initial: :pending do
+ state :pending, value: 'pending'
+ state :running, value: 'running'
+ state :failed, value: 'failed'
+ state :success, value: 'success'
+ state :canceled, value: 'canceled'
+ state :skipped, value: 'skipped'
+ end
+
+ scope :running, -> { where(status: 'running') }
+ scope :pending, -> { where(status: 'pending') }
+ scope :success, -> { where(status: 'success') }
+ scope :failed, -> { where(status: 'failed') }
+ scope :canceled, -> { where(status: 'canceled') }
+ scope :skipped, -> { where(status: 'skipped') }
+ scope :running_or_pending, -> { where(status: [:running, :pending]) }
+ scope :finished, -> { where(status: [:success, :failed, :canceled]) }
+ end
+
+ def started?
+ !pending? && !canceled? && started_at
+ end
+
+ def active?
+ running? || pending?
+ end
+
+ def complete?
+ canceled? || success? || failed?
+ end
+end