1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
# frozen_string_literal: true
class DraftNote < ApplicationRecord
include DiffPositionableNote
include Gitlab::Utils::StrongMemoize
include Sortable
include ShaAttribute
include BulkInsertSafe
PUBLISH_ATTRS = %i[noteable type note internal].freeze
DIFF_ATTRS = %i[position original_position change_position commit_id].freeze
sha_attribute :commit_id
# Attribute used to store quick actions changes and users referenced.
attr_accessor :commands_changes
attr_accessor :users_referenced
# Text with quick actions filtered out
attr_accessor :rendered_note
attr_accessor :review
belongs_to :author, class_name: 'User'
belongs_to :merge_request
validates :merge_request_id, presence: true
validates :author_id, presence: true, uniqueness: { scope: [:merge_request_id, :discussion_id] }, if: :discussion_id?
validates :discussion_id, allow_nil: true, format: { with: /\A\h{40}\z/ }
validates :line_code, length: { maximum: 255 }, allow_nil: true
enum note_type: {
Note: 0,
DiffNote: 1,
DiscussionNote: 2
}
scope :authored_by, ->(u) { where(author_id: u.id) }
delegate :file_path, :file_hash, :file_identifier_hash, to: :diff_file, allow_nil: true
def self.positions
where.not(position: nil)
.select(:position)
.map(&:position)
end
def project
merge_request.target_project
end
# noteable_id and noteable_type methods
# are used to generate discussion_id on Discussion.discussion_id
def noteable_id
merge_request_id
end
def noteable
merge_request
end
def noteable_type
"MergeRequest"
end
def for_commit?
commit_id.present?
end
def importing?
false
end
def resolvable?
false
end
def emoji_awardable?
false
end
def on_diff?
position&.complete?
end
def type
return note_type if note_type.present?
return 'DiffNote' if on_diff?
return 'DiscussionNote' if discussion_id.present?
'Note'
end
def references
{
users: users_referenced,
commands: commands_changes
}
end
def line_code
super.presence || find_line_code
end
def find_line_code
write_attribute(:line_code, diff_file&.line_code_for_position(original_position))
end
def publish_params
attrs = PUBLISH_ATTRS.dup
attrs.concat(DIFF_ATTRS) if on_diff?
params = slice(*attrs)
params[:in_reply_to_discussion_id] = discussion_id if discussion_id.present?
params[:review_id] = review.id if review.present?
params.except("internal") if on_diff?
params
end
def self.preload_author(draft_notes)
ActiveRecord::Associations::Preloader.new(records: draft_notes, associations: { author: :status }).call
end
def diff_file
strong_memoize(:diff_file) do
file = original_position&.diff_file(project.repository)
file&.unfold_diff_lines(original_position)
file
end
end
def commit
@commit ||= project.commit(commit_id) if commit_id.present?
end
end
|