issuable.rb 2.5 KB
Newer Older
1
# == Issuable concern
D
Dmitriy Zaporozhets 已提交
2
#
3
# Contains common functionality shared between Issues and MergeRequests
D
Dmitriy Zaporozhets 已提交
4 5 6
#
# Used by Issue, MergeRequest
#
7
module Issuable
8
  extend ActiveSupport::Concern
9
  include Mentionable
10 11

  included do
12 13
    belongs_to :author, class_name: "User"
    belongs_to :assignee, class_name: "User"
14
    belongs_to :milestone
15
    has_many :notes, as: :noteable, dependent: :destroy
16

A
Andrey Kumanyaev 已提交
17 18
    validates :author, presence: true
    validates :title, presence: true, length: { within: 0..255 }
D
Dmitriy Zaporozhets 已提交
19
    validate :set_iid, on: :create
20
    validates :iid, presence: true, numericality: true
21

22
    scope :authored, ->(user) { where(author_id: user) }
23
    scope :assigned_to, ->(u) { where(assignee_id: u.id)}
A
Andrew8xx8 已提交
24
    scope :recent, -> { order("created_at DESC") }
25 26
    scope :assigned, -> { where("assignee_id IS NOT NULL") }
    scope :unassigned, -> { where("assignee_id IS NULL") }
27
    scope :of_projects, ->(ids) { where(project_id: ids) }
28

29

30 31
    delegate :name,
             :email,
32 33
             to: :author,
             prefix: true
34 35 36

    delegate :name,
             :email,
37 38 39
             to: :assignee,
             allow_nil: true,
             prefix: true
40 41 42 43

    attr_accessor :author_id_of_changes
  end

44 45
  module ClassMethods
    def search(query)
46
      where("title like :query", query: "%#{query}%")
47
    end
48 49
  end

50 51 52 53 54 55 56 57 58
  def set_iid
    max_iid = project.send(self.class.name.tableize).maximum(:iid)
    self.iid = max_iid.to_i + 1
  end

  def to_param
    iid.to_s
  end

59 60 61 62 63 64 65
  def today?
    Date.today == created_at.to_date
  end

  def new?
    today? && created_at == updated_at
  end
66 67 68 69 70 71 72 73 74

  def is_assigned?
    !!assignee_id
  end

  def is_being_reassigned?
    assignee_id_changed?
  end

75 76 77 78 79 80 81
  #
  # Votes
  #

  # Return the number of -1 comments (downvotes)
  def downvotes
    notes.select(&:downvote?).size
82 83
  end

84
  def downvotes_in_percent
85 86 87
    if votes_count.zero?
      0
    else
88
      100.0 - upvotes_in_percent
89 90 91
    end
  end

92 93 94
  # Return the number of +1 comments (upvotes)
  def upvotes
    notes.select(&:upvote?).size
95 96
  end

97
  def upvotes_in_percent
98 99 100
    if votes_count.zero?
      0
    else
101
      100.0 / votes_count * upvotes
102 103 104 105 106 107 108
    end
  end

  # Return the total number of votes
  def votes_count
    upvotes + downvotes
  end
109 110 111 112 113 114 115 116 117 118 119 120 121 122

  # Return all users participating on the discussion
  def participants
    users = []
    users << author
    users << assignee if is_assigned?
    mentions = []
    mentions << self.mentioned_users
    notes.each do |note|
      users << note.author
      mentions << note.mentioned_users
    end
    users.concat(mentions.reduce([], :|)).uniq
  end
123
end