issuable.rb 2.23 KB
Newer Older
1
# == Issuable concern
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
2
#
3
# Contains common functionality shared between Issues and MergeRequests
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
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

Andrey Kumanyaev's avatar
Andrey Kumanyaev committed
17 18
    validates :author, presence: true
    validates :title, presence: true, length: { within: 0..255 }
19

20
    scope :assigned_to, ->(u) { where(assignee_id: u.id)}
Andrew8xx8's avatar
Andrew8xx8 committed
21
    scope :recent, -> { order("created_at DESC") }
22 23
    scope :assigned, -> { where("assignee_id IS NOT NULL") }
    scope :unassigned, -> { where("assignee_id IS NULL") }
24
    scope :of_projects, ->(ids) { where(project_id: ids) }
25 26 27

    delegate :name,
             :email,
28 29
             to: :author,
             prefix: true
30 31 32

    delegate :name,
             :email,
33 34 35
             to: :assignee,
             allow_nil: true,
             prefix: true
36 37 38 39

    attr_accessor :author_id_of_changes
  end

40 41
  module ClassMethods
    def search(query)
42
      where("title like :query", query: "%#{query}%")
43
    end
44 45 46 47 48 49 50 51 52
  end

  def today?
    Date.today == created_at.to_date
  end

  def new?
    today? && created_at == updated_at
  end
53 54 55 56 57 58 59 60 61

  def is_assigned?
    !!assignee_id
  end

  def is_being_reassigned?
    assignee_id_changed?
  end

62 63 64 65 66 67 68
  #
  # Votes
  #

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

71
  def downvotes_in_percent
72 73 74
    if votes_count.zero?
      0
    else
75
      100.0 - upvotes_in_percent
76 77 78
    end
  end

79 80 81
  # Return the number of +1 comments (upvotes)
  def upvotes
    notes.select(&:upvote?).size
82 83
  end

84
  def upvotes_in_percent
85 86 87
    if votes_count.zero?
      0
    else
88
      100.0 / votes_count * upvotes
89 90 91 92 93 94 95
    end
  end

  # Return the total number of votes
  def votes_count
    upvotes + downvotes
  end
96 97 98 99 100 101 102 103 104 105 106 107 108 109

  # 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
110
end