Class: Milestone

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
InternalId, Milestoneish, Referable, Sortable, StripAttribute
Defined in:
app/models/milestone.rb

Overview

Schema Information

Table name: milestones

id          :integer          not null, primary key
title       :string           not null
project_id  :integer          not null
description :text
due_date    :date
created_at  :datetime
updated_at  :datetime
state       :string
iid         :integer

Defined Under Namespace

Classes: MilestoneStruct

Constant Summary collapse

None =
MilestoneStruct.new('No Milestone', 'No Milestone', 0)
Any =
MilestoneStruct.new('Any Milestone', '', -1)
Upcoming =
MilestoneStruct.new('Upcoming', '#upcoming', -2)

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Milestoneish

#closed_items_count, #complete?, #issues_visible_to_user, #percent_complete, #remaining_days, #total_items_count

Methods included from StripAttribute

#strip_attributes

Methods included from InternalId

#set_iid, #to_param

Class Method Details


81
82
83
# File 'app/models/milestone.rb', line 81

def self.link_reference_pattern
  @link_reference_pattern ||= super("milestones", /(?<milestone>\d+)/)
end

.reference_patternObject


77
78
79
# File 'app/models/milestone.rb', line 77

def self.reference_pattern
  nil
end

.search(query) ⇒ Object

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.


69
70
71
72
73
74
# File 'app/models/milestone.rb', line 69

def search(query)
  t = arel_table
  pattern = "%#{query}%"

  where(t[:title].matches(pattern).or(t[:description].matches(pattern)))
end

.upcomingObject


85
86
87
# File 'app/models/milestone.rb', line 85

def self.upcoming
  self.where('due_date > ?', Time.now).reorder(due_date: :asc).first
end

Instance Method Details

#author_idObject


128
129
130
# File 'app/models/milestone.rb', line 128

def author_id
  nil
end

#can_be_closed?Boolean

Returns:

  • (Boolean)

120
121
122
# File 'app/models/milestone.rb', line 120

def can_be_closed?
  active? && issues.opened.count.zero?
end

#expired?Boolean

Returns:

  • (Boolean)

102
103
104
105
106
107
108
# File 'app/models/milestone.rb', line 102

def expired?
  if due_date
    due_date.past?
  else
    false
  end
end

#expires_atObject


110
111
112
113
114
115
116
117
118
# File 'app/models/milestone.rb', line 110

def expires_at
  if due_date
    if due_date.past?
      "expired on #{due_date.to_s(:medium)}"
    else
      "expires on #{due_date.to_s(:medium)}"
    end
  end
end

#is_empty?(user = nil) ⇒ Boolean

Returns:

  • (Boolean)

124
125
126
# File 'app/models/milestone.rb', line 124

def is_empty?(user = nil)
  total_items_count(user).zero?
end

98
99
100
# File 'app/models/milestone.rb', line 98

def reference_link_text(from_project = nil)
  self.title
end

#sort_issues(ids) ⇒ Object

Sorts the issues for the given IDs.

This method runs a single SQL query using a CASE statement to update the position of all issues in the current milestone (scoped to the list of IDs).

Given the ids [10, 20, 30] this method produces a SQL query something like the following:

UPDATE issues
SET position = CASE
  WHEN id = 10 THEN 1
  WHEN id = 20 THEN 2
  WHEN id = 30 THEN 3
  ELSE position
END
WHERE id IN (10, 20, 30);

This method expects that the IDs given in `ids` are already Fixnums.


150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'app/models/milestone.rb', line 150

def sort_issues(ids)
  pairs = []

  ids.each_with_index do |id, index|
    pairs << id
    pairs << index + 1
  end

  conditions = 'WHEN id = ? THEN ? ' * ids.length

  issues.where(id: ids).
    update_all(["position = CASE #{conditions} ELSE position END", *pairs])
end

#to_reference(from_project = nil) ⇒ Object


89
90
91
92
93
94
95
96
# File 'app/models/milestone.rb', line 89

def to_reference(from_project = nil)
  escaped_title = self.title.gsub("]", "\\]")

  h = Gitlab::Routing.url_helpers
  url = h.namespace_project_milestone_url(self.project.namespace, self.project, self)

  "[#{escaped_title}](#{url})"
end