summaryrefslogtreecommitdiff
path: root/app/models/milestone.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/milestone.rb')
-rw-r--r--app/models/milestone.rb58
1 files changed, 21 insertions, 37 deletions
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index cbe65d70997..de7183bf6b4 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -19,17 +19,19 @@ class Milestone < ActiveRecord::Base
MilestoneStruct = Struct.new(:title, :name, :id)
None = MilestoneStruct.new('No Milestone', 'No Milestone', 0)
Any = MilestoneStruct.new('Any Milestone', '', -1)
+ Upcoming = MilestoneStruct.new('Upcoming', '#upcoming', -2)
include InternalId
include Sortable
include Referable
include StripAttribute
+ include Milestoneish
belongs_to :project
has_many :issues
- has_many :labels, through: :issues
+ has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues
has_many :merge_requests
- has_many :participants, through: :issues, source: :assignee
+ has_many :participants, -> { distinct.reorder('users.name') }, through: :issues, source: :assignee
scope :active, -> { with_state(:active) }
scope :closed, -> { with_state(:closed) }
@@ -57,9 +59,18 @@ class Milestone < ActiveRecord::Base
alias_attribute :name, :title
class << self
+ # Searches for milestones matching the given query.
+ #
+ # This method uses ILIKE on PostgreSQL and LIKE on MySQL.
+ #
+ # query - The search query as a String
+ #
+ # Returns an ActiveRecord::Relation.
def search(query)
- query = "%#{query}%"
- where("title like ? or description like ?", query, query)
+ t = arel_table
+ pattern = "%#{query}%"
+
+ where(t[:title].matches(pattern).or(t[:description].matches(pattern)))
end
end
@@ -71,6 +82,10 @@ class Milestone < ActiveRecord::Base
super("milestones", /(?<milestone>\d+)/)
end
+ def self.upcoming
+ self.where('due_date > ?', Time.now).order(due_date: :asc).first
+ end
+
def to_reference(from_project = nil)
escaped_title = self.title.gsub("]", "\\]")
@@ -92,37 +107,6 @@ class Milestone < ActiveRecord::Base
end
end
- def open_items_count
- self.issues.opened.count + self.merge_requests.opened.count
- end
-
- def closed_items_count
- self.issues.closed.count + self.merge_requests.closed_and_merged.count
- end
-
- def total_items_count
- self.issues.count + self.merge_requests.count
- end
-
- def percent_complete
- ((closed_items_count * 100) / total_items_count).abs
- rescue ZeroDivisionError
- 0
- end
-
- # Returns the elapsed time (in percent) since the Milestone creation date until today.
- # If the Milestone doesn't have a due_date then returns 0 since we can't calculate the elapsed time.
- # If the Milestone is overdue then it returns 100%.
- def percent_time_used
- return 0 unless due_date
- return 100 if expired?
-
- duration = ((created_at - due_date.to_datetime) / 1.day)
- days_elapsed = ((created_at - Time.now) / 1.day)
-
- ((days_elapsed.to_f / duration) * 100).floor
- end
-
def expires_at
if due_date
if due_date.past?
@@ -137,8 +121,8 @@ class Milestone < ActiveRecord::Base
active? && issues.opened.count.zero?
end
- def is_empty?
- total_items_count.zero?
+ def is_empty?(user = nil)
+ total_items_count(user).zero?
end
def author_id