Class: Discussion
Overview
A non-diff discussion on an issue, merge request, commit, or snippet, consisting of ‘DiscussionNote` notes.
A discussion of this type can be resolvable.
Constant Summary
collapse
- CACHE_VERSION =
Bump this if we need to refresh the cached versions of discussions
1
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#can_resolve?, #clear_memoized_values, #first_note, #first_note_to_resolve, #last_resolved_note, #resolvable?, #resolve!, #resolved?, #resolved_by_push?, #resolved_notes, #to_be_resolved?, #unresolve!
Constructor Details
#initialize(notes, context_noteable = nil) ⇒ Discussion
Returns a new instance of Discussion.
106
107
108
109
|
# File 'app/models/discussion.rb', line 106
def initialize(notes, context_noteable = nil)
@notes = notes
@context_noteable = context_noteable
end
|
Instance Attribute Details
#context_noteable ⇒ Object
Returns the value of attribute context_noteable.
13
14
15
|
# File 'app/models/discussion.rb', line 13
def context_noteable
@context_noteable
end
|
#notes ⇒ Object
Returns the value of attribute notes.
14
15
16
|
# File 'app/models/discussion.rb', line 14
def notes
@notes
end
|
Class Method Details
.base_discussion_id(note) ⇒ Object
80
81
82
83
|
# File 'app/models/discussion.rb', line 80
def self.base_discussion_id(note)
noteable_id = note.noteable_id || note.commit_id
[:discussion, note.noteable_type.try(:underscore), noteable_id]
end
|
.build(notes, context_noteable = nil) ⇒ Object
42
43
44
|
# File 'app/models/discussion.rb', line 42
def self.build(notes, context_noteable = nil)
notes.first.discussion_class(context_noteable).new(notes, context_noteable)
end
|
.build_collection(notes, context_noteable = nil) ⇒ Object
46
47
48
49
|
# File 'app/models/discussion.rb', line 46
def self.build_collection(notes, context_noteable = nil)
grouped_notes = notes.group_by { |n| n.discussion_id(context_noteable) }
grouped_notes.values.map { |notes| build(notes, context_noteable) }
end
|
.build_discussion_id(note) ⇒ Object
Returns an array of discussion ID components
76
77
78
|
# File 'app/models/discussion.rb', line 76
def self.build_discussion_id(note)
[*base_discussion_id(note), SecureRandom.hex]
end
|
.build_discussions(discussion_ids, context_noteable = nil, preload_note_diff_file: false) ⇒ Object
51
52
53
54
55
56
57
|
# File 'app/models/discussion.rb', line 51
def self.build_discussions(discussion_ids, context_noteable = nil, preload_note_diff_file: false)
notes = Note.where(discussion_id: discussion_ids).fresh
notes = notes.inc_note_diff_file if preload_note_diff_file
grouped_notes = notes.group_by { |n| n.discussion_id }
grouped_notes.transform_values { |notes| Discussion.build(notes, context_noteable) }
end
|
.discussion_id(note) ⇒ Object
Returns an alphanumeric discussion ID based on ‘build_discussion_id`
71
72
73
|
# File 'app/models/discussion.rb', line 71
def self.discussion_id(note)
Digest::SHA1.hexdigest(build_discussion_id(note).join("-"))
end
|
.lazy_find(discussion_id) ⇒ Object
59
60
61
62
63
64
65
66
67
68
|
# File 'app/models/discussion.rb', line 59
def self.lazy_find(discussion_id)
BatchLoader.for(discussion_id).batch do |discussion_ids, loader|
results = Note.where(discussion_id: discussion_ids).fresh.to_a.group_by(&:discussion_id)
results.each do |discussion_id, notes|
next if notes.empty?
loader.call(discussion_id, Discussion.build(notes))
end
end
end
|
.note_class ⇒ Object
102
103
104
|
# File 'app/models/discussion.rb', line 102
def self.note_class
DiscussionNote
end
|
.override_discussion_id(note) ⇒ Object
When notes on a commit are displayed in context of a merge request that contains that commit, these notes are to be displayed as if they were part of one discussion, even though they were actually individual notes on the commit with different discussion IDs, so that it’s clear that these are not notes on the merge request itself.
To turn a list of notes into a list of discussions, they are grouped by discussion ID, so to get these out-of-context notes to end up in the same discussion, we need to get them to return the same ‘discussion_id` when this grouping happens. To enable this, `Note#discussion_id` calls out to the `override_discussion_id` method on the appropriate `Discussion` subclass, as determined by the `discussion_class` method on `Note` or a subclass of `Note`.
If no override is necessary, return ‘nil`. For the case described above, see `OutOfContextDiscussion.override_discussion_id`.
98
99
100
|
# File 'app/models/discussion.rb', line 98
def self.override_discussion_id(note)
nil
end
|
Instance Method Details
#==(other) ⇒ Object
115
116
117
118
119
120
|
# File 'app/models/discussion.rb', line 115
def ==(other)
other.class == self.class &&
other.context_noteable == self.context_noteable &&
other.id == self.id &&
other.notes == self.notes
end
|
#cache_key ⇒ Object
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# File 'app/models/discussion.rb', line 174
def cache_key
notes_sha = Digest::SHA1.hexdigest(notes.map(&:post_processed_cache_key).join(':'))
[
CACHE_VERSION,
id,
notes_sha,
resolved_at
].join(':')
end
|
#can_convert_to_discussion? ⇒ Boolean
154
155
156
|
# File 'app/models/discussion.rb', line 154
def can_convert_to_discussion?
false
end
|
#collapsed? ⇒ Boolean
162
163
164
|
# File 'app/models/discussion.rb', line 162
def collapsed?
resolved?
end
|
#declarative_policy_delegate ⇒ Object
34
35
36
|
# File 'app/models/discussion.rb', line 34
def declarative_policy_delegate
first_note
end
|
#diff_discussion? ⇒ Boolean
146
147
148
|
# File 'app/models/discussion.rb', line 146
def diff_discussion?
false
end
|
#expanded? ⇒ Boolean
166
167
168
|
# File 'app/models/discussion.rb', line 166
def expanded?
!collapsed?
end
|
#id ⇒ Object
Also known as:
to_param
134
135
136
|
# File 'app/models/discussion.rb', line 134
def id
first_note.discussion_id(context_noteable)
end
|
#individual_note? ⇒ Boolean
150
151
152
|
# File 'app/models/discussion.rb', line 150
def individual_note?
false
end
|
#last_note ⇒ Object
158
159
160
|
# File 'app/models/discussion.rb', line 158
def last_note
@last_note ||= notes.last
end
|
#last_updated_at ⇒ Object
122
123
124
|
# File 'app/models/discussion.rb', line 122
def last_updated_at
last_note.created_at
end
|
#last_updated_by ⇒ Object
126
127
128
|
# File 'app/models/discussion.rb', line 126
def last_updated_by
last_note.author
end
|
#noteable_collection_name ⇒ Object
195
196
197
|
# File 'app/models/discussion.rb', line 195
def noteable_collection_name
noteable.class.underscore.pluralize
end
|
#on_image? ⇒ Boolean
111
112
113
|
# File 'app/models/discussion.rb', line 111
def on_image?
false
end
|
#project_id ⇒ Object
38
39
40
|
# File 'app/models/discussion.rb', line 38
def project_id
project&.id
end
|
#reply_attributes ⇒ Object
170
171
172
|
# File 'app/models/discussion.rb', line 170
def reply_attributes
first_note.slice(:type, :noteable_type, :noteable_id, :commit_id, :discussion_id)
end
|
#reply_id ⇒ Object
138
139
140
141
142
|
# File 'app/models/discussion.rb', line 138
def reply_id
first_note.discussion_id
end
|
#to_global_id(options = {}) ⇒ Object
Consolidate discussions GID. There is no need to have different GID for different class names as the discussion_id hash is already unique per discussion. This also fixes the issue where same discussion may return different GIDs depending on number of notes it has.
191
192
193
|
# File 'app/models/discussion.rb', line 191
def to_global_id(options = {})
GlobalID.new(::Gitlab::GlobalId.build(model_name: Discussion.to_s, id: id))
end
|
#updated? ⇒ Boolean
130
131
132
|
# File 'app/models/discussion.rb', line 130
def updated?
last_updated_at != created_at
end
|