Class: Note
- Inherits:
-
ApplicationRecord
show all
- Extended by:
- ActiveModel::Naming, Gitlab::Utils::Override
- Includes:
- AfterCommitQueue, Awardable, CacheMarkdownField, EachBatch, Editable, FasterCacheKeys, FromUnion, Gitlab::SQL::Pattern, Gitlab::Utils::StrongMemoize, IgnorableColumns, Importable, Mentionable, Participable, Redactable, ResolvableNote, Sortable, Spammable, ThrottledTouch
- Defined in:
- app/models/note.rb
Overview
A note on the root of an issue, merge request, commit, or snippet.
A note of this type is never resolvable.
Constant Summary
collapse
- ISSUE_TASK_SYSTEM_NOTE_PATTERN =
/\A.*marked\sthe\stask.+as\s(completed|incomplete).*\z/
- TYPES_RESTRICTED_BY_PROJECT_ABILITY =
{
branch: :download_code
}.freeze
- TYPES_RESTRICTED_BY_GROUP_ABILITY =
{
contact: :read_crm_contact
}.freeze
- NON_DIFF_NOTE_TYPES =
['Note', 'DiscussionNote', nil].freeze
ThrottledTouch::TOUCH_INTERVAL
Gitlab::SQL::Pattern::MIN_CHARS_FOR_PARTIAL_MATCHING, Gitlab::SQL::Pattern::REGEX_QUOTED_TERM
ResolvableNote::RESOLVABLE_TYPES
CacheMarkdownField::INVALIDATED_BY
Constants included
from Redactable
Redactable::UNSUBSCRIBE_PATTERN
ApplicationRecord::MAX_PLUCK
ResetOnUnionError::MAX_RESET_PERIOD
Instance Attribute Summary collapse
#skip_markdown_cache_validation
Attributes included from Importable
#imported, #importing
Class Method Summary
collapse
Instance Method Summary
collapse
extended, extensions, included, method_added, override, prepended, queue_verification, verify!
Methods included from Spammable
#allow_possible_spam?, #check_for_spam, #clear_spam_flags!, #invalidate_if_spam, #needs_recaptcha!, #recaptcha_error!, #render_recaptcha?, #spam, #spam!, #spam_description, #spam_title, #spammable_attribute_changed?, #spammable_entity_type, #spammable_text, #submittable_as_spam?, #submittable_as_spam_by?, #supports_recaptcha?, #unrecoverable_spam_error!
split_query_to_search_terms
Methods included from Editable
#last_edited_by
#potentially_resolvable?, #resolvable?, #resolve!, #resolve_without_save, #resolved?, #to_be_resolved?, #unresolve!, #unresolve_without_save
#run_after_commit, #run_after_commit_or_now
#attribute_invalidated?, #cached_html_for, #cached_html_up_to_date?, #can_cache_field?, #invalidated_markdown_cache?, #latest_cached_markdown_version, #local_version, #mentionable_attributes_changed?, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #store_mentions!, #updated_cached_html_for
#cache_key
Methods included from Awardable
#awarded_emoji?, #downvotes, #grouped_awards, #upvotes, #user_authored?, #user_can_award?
#all_references, #create_cross_references!, #create_new_cross_references!, #directly_addressed_users, #extractors, #gfm_reference, #local_reference, #matches_cross_reference_regex?, #referenced_group_users, #referenced_groups, #referenced_mentionables, #referenced_project_users, #referenced_projects, #referenced_users
#participant?, #participants, #visible_participants
cached_column_list, #create_or_load_association, declarative_enum, default_select_columns, id_in, id_not_in, iid_in, pluck_primary_key, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order
#serializable_hash
Instance Attribute Details
#command_names ⇒ Object
Attribute used to store the quick action command names.
65
66
67
|
# File 'app/models/note.rb', line 65
def command_names
@command_names
end
|
#commands_changes ⇒ Object
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
|
# File 'app/models/note.rb', line 706
def commands_changes
@commands_changes&.slice(
:due_date,
:label_ids,
:remove_label_ids,
:add_label_ids,
:canonical_issue_id,
:clone_with_notes,
:confidential,
:create_merge_request,
:add_contacts,
:remove_contacts,
:assignee_ids,
:milestone_id,
:time_estimate,
:spend_time,
:discussion_locked,
:merge,
:rebase,
:wip_event,
:target_branch,
:reviewer_ids,
:health_status,
:promote_to_epic,
:weight,
:emoji_award,
:todo_event,
:subscription_event,
:state_event,
:title,
:tag_message,
:tag_name
)
end
|
#redacted_note_html ⇒ Object
Attribute containing rendered and redacted Markdown as generated by Banzai::ObjectRenderer.
53
54
55
|
# File 'app/models/note.rb', line 53
def redacted_note_html
@redacted_note_html
end
|
#skip_keep_around_commits ⇒ Object
Attribute used to determine whether keep_around_commits will be skipped for diff notes.
68
69
70
|
# File 'app/models/note.rb', line 68
def skip_keep_around_commits
@skip_keep_around_commits
end
|
#total_reference_count ⇒ Object
Total of all references as generated by Banzai::ObjectRenderer
56
57
58
|
# File 'app/models/note.rb', line 56
def total_reference_count
@total_reference_count
end
|
#user_visible_reference_count ⇒ Object
Number of user visible references as generated by Banzai::ObjectRenderer
59
60
61
|
# File 'app/models/note.rb', line 59
def user_visible_reference_count
@user_visible_reference_count
end
|
Class Method Details
.cherry_picked_merge_requests(shas) ⇒ Object
308
309
310
|
# File 'app/models/note.rb', line 308
def cherry_picked_merge_requests(shas)
where(noteable_type: 'MergeRequest', commit_id: shas).select(:noteable_id)
end
|
.count_for_collection(ids, type, count_column = 'COUNT(*) as count') ⇒ Object
291
292
293
294
295
|
# File 'app/models/note.rb', line 291
def count_for_collection(ids, type, count_column = 'COUNT(*) as count')
user.select(:noteable_id, count_column)
.group(:noteable_id)
.where(noteable_type: type, noteable_id: ids)
end
|
.discussions(context_noteable = nil) ⇒ Object
248
249
250
|
# File 'app/models/note.rb', line 248
def discussions(context_noteable = nil)
Discussion.build_collection(all.includes(:noteable).fresh, context_noteable)
end
|
.find_discussion(discussion_id) ⇒ Object
Note: Where possible consider using Discussion#lazy_find to return Discussions in order to benefit from having records batch loaded.
254
255
256
257
258
259
260
|
# File 'app/models/note.rb', line 254
def find_discussion(discussion_id)
notes = where(discussion_id: discussion_id).fresh.to_a
return if notes.empty?
Discussion.build(notes)
end
|
.grouped_diff_discussions(diff_refs = nil) ⇒ Object
Group diff discussions by line code or file path. It is not needed to group by line code when comment is on an image.
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
# File 'app/models/note.rb', line 265
def grouped_diff_discussions(diff_refs = nil)
groups = {}
diff_notes.fresh.discussions.each do |discussion|
group_key =
if discussion.on_image?
discussion.file_new_path
else
discussion.line_code_in_diffs(diff_refs)
end
if group_key
discussions = groups[group_key] ||= []
discussions << discussion
end
end
groups
end
|
.model_name ⇒ Object
244
245
246
|
# File 'app/models/note.rb', line 244
def model_name
ActiveModel::Name.new(self, nil, 'note')
end
|
.positions ⇒ Object
285
286
287
288
289
|
# File 'app/models/note.rb', line 285
def positions
where.not(position: nil)
.select(:id, :type, :position) .map(&:position)
end
|
.search(query) ⇒ Object
297
298
299
|
# File 'app/models/note.rb', line 297
def search(query)
fuzzy_search(query, [:note])
end
|
.simple_sorts ⇒ Object
304
305
306
|
# File 'app/models/note.rb', line 304
def simple_sorts
super.except('name_asc', 'name_desc')
end
|
.with_web_entity_associations ⇒ Object
312
313
314
|
# File 'app/models/note.rb', line 312
def with_web_entity_associations
preload(:project, :author, :noteable)
end
|
Instance Method Details
#active? ⇒ Boolean
333
334
335
|
# File 'app/models/note.rb', line 333
def active?
true
end
|
#attribute_names_for_serialization ⇒ Object
Use attributes.keys instead of attribute_names to filter out the fields that are skipped during export:
-
note_html
-
cached_markdown_version
800
801
802
|
# File 'app/models/note.rb', line 800
def attribute_names_for_serialization
attributes.keys
end
|
#award_emoji? ⇒ Boolean
473
474
475
|
# File 'app/models/note.rb', line 473
def award_emoji?
can_be_award_emoji? && contains_emoji_only?
end
|
#banzai_render_context(field) ⇒ Object
641
642
643
|
# File 'app/models/note.rb', line 641
def banzai_render_context(field)
super.merge(noteable: noteable, system_note: system?, label_url_method: noteable_label_url_method)
end
|
#broadcast_noteable_notes_changed ⇒ Object
594
595
596
|
# File 'app/models/note.rb', line 594
def broadcast_noteable_notes_changed
noteable&.broadcast_notes_changed
end
|
#bump_updated_at ⇒ Object
579
580
581
582
583
584
585
586
587
588
589
590
591
592
|
# File 'app/models/note.rb', line 579
def bump_updated_at
attributes_to_update = { updated_at: Time.current }
if updated_by_id.present? && read_attribute(:last_edited_at).blank?
attributes_to_update[:last_edited_at] = updated_at
end
update_columns(attributes_to_update)
end
|
#can_be_award_emoji? ⇒ Boolean
481
482
483
|
# File 'app/models/note.rb', line 481
def can_be_award_emoji?
noteable.is_a?(Awardable) && !part_of_discussion?
end
|
#can_be_discussion_note? ⇒ Boolean
501
502
503
|
# File 'app/models/note.rb', line 501
def can_be_discussion_note?
self.noteable.supports_discussions? && !part_of_discussion? && !system?
end
|
#can_create_todo? ⇒ Boolean
505
506
507
508
|
# File 'app/models/note.rb', line 505
def can_create_todo?
!system? && !for_snippet?
end
|
#check_for_spam? ⇒ Boolean
Override method defined in Spammable Wildcard argument because user: argument is not used
788
789
790
791
792
793
794
|
# File 'app/models/note.rb', line 788
def check_for_spam?(*)
return false if system? || !spammable_attribute_changed? || confidential?
return false if noteable.try(:confidential?) == true || noteable.try(:public?) == false
return false if noteable.try(:group)&.public? == false || project&.public? == false
true
end
|
#commit ⇒ Object
401
402
403
|
# File 'app/models/note.rb', line 401
def commit
@commit ||= project.commit(commit_id) if commit_id.present?
end
|
#confidential?(include_noteable: false) ⇒ Boolean
449
450
451
452
453
|
# File 'app/models/note.rb', line 449
def confidential?(include_noteable: false)
return true if confidential
include_noteable && noteable.try(:confidential?)
end
|
#contains_emoji_only? ⇒ Boolean
#contributor? ⇒ Boolean
433
434
435
|
# File 'app/models/note.rb', line 433
def contributor?
project&.team&.contributor?(self.author_id)
end
|
#diff_note? ⇒ Boolean
rubocop: enable CodeReuse/ServiceClass
329
330
331
|
# File 'app/models/note.rb', line 329
def diff_note?
false
end
|
#discussion ⇒ Object
Returns the entire discussion this note is part of. Consider using ‘#to_discussion` if we do not need to render the discussion and all its notes and if we don’t care about the discussion’s resolvability status.
537
538
539
540
541
542
|
# File 'app/models/note.rb', line 537
def discussion
strong_memoize(:discussion) do
full_discussion = self.noteable.notes.find_discussion(self.discussion_id) if self.noteable && part_of_discussion?
full_discussion || to_discussion
end
end
|
#discussion_class(noteable = nil) ⇒ Object
#discussion_id(noteable = nil) ⇒ Object
See ‘Discussion.override_discussion_id` for details.
522
523
524
|
# File 'app/models/note.rb', line 522
def discussion_id(noteable = nil)
discussion_class(noteable).override_discussion_id(self) || super() || ensure_discussion_id
end
|
#editable? ⇒ Boolean
455
456
457
|
# File 'app/models/note.rb', line 455
def editable?
!system?
end
|
#edited? ⇒ Boolean
Since we used ‘updated_at` as `last_edited_at`, it could be touched by transforming / resolving a note. This makes sure it is only marked as edited when the note body is updated.
467
468
469
470
471
|
# File 'app/models/note.rb', line 467
def edited?
return false if updated_by.blank?
super
end
|
#emoji_awardable? ⇒ Boolean
477
478
479
|
# File 'app/models/note.rb', line 477
def emoji_awardable?
!system?
end
|
#exportable_record?(user) ⇒ Boolean
780
781
782
783
784
|
# File 'app/models/note.rb', line 780
def exportable_record?(user)
return true unless system?
readable_by?(user)
end
|
#for_alert_mangement_alert? ⇒ Boolean
369
370
371
|
# File 'app/models/note.rb', line 369
def for_alert_mangement_alert?
noteable_type == 'AlertManagement::Alert'
end
|
#for_commit? ⇒ Boolean
349
350
351
|
# File 'app/models/note.rb', line 349
def for_commit?
noteable_type == "Commit"
end
|
#for_design? ⇒ Boolean
389
390
391
|
# File 'app/models/note.rb', line 389
def for_design?
noteable_type == DesignManagement::Design.name
end
|
#for_issuable? ⇒ Boolean
393
394
395
|
# File 'app/models/note.rb', line 393
def for_issuable?
for_issue? || for_merge_request?
end
|
#for_issue? ⇒ Boolean
353
354
355
|
# File 'app/models/note.rb', line 353
def for_issue?
noteable_type == "Issue"
end
|
#for_merge_request? ⇒ Boolean
361
362
363
|
# File 'app/models/note.rb', line 361
def for_merge_request?
noteable_type == "MergeRequest"
end
|
#for_personal_snippet? ⇒ Boolean
381
382
383
|
# File 'app/models/note.rb', line 381
def for_personal_snippet?
noteable.is_a?(PersonalSnippet)
end
|
#for_project_noteable? ⇒ Boolean
385
386
387
|
# File 'app/models/note.rb', line 385
def for_project_noteable?
!for_personal_snippet?
end
|
#for_project_snippet? ⇒ Boolean
377
378
379
|
# File 'app/models/note.rb', line 377
def for_project_snippet?
noteable.is_a?(ProjectSnippet)
end
|
#for_snippet? ⇒ Boolean
365
366
367
|
# File 'app/models/note.rb', line 365
def for_snippet?
noteable_type == "Snippet"
end
|
#for_vulnerability? ⇒ Boolean
373
374
375
|
# File 'app/models/note.rb', line 373
def for_vulnerability?
noteable_type == "Vulnerability"
end
|
#for_work_item? ⇒ Boolean
357
358
359
|
# File 'app/models/note.rb', line 357
def for_work_item?
noteable.is_a?(WorkItem)
end
|
#human_max_access ⇒ Object
437
438
439
|
# File 'app/models/note.rb', line 437
def human_max_access
project&.team&.human_max_access(self.author_id)
end
|
#in_reply_to?(other) ⇒ Boolean
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
|
# File 'app/models/note.rb', line 552
def in_reply_to?(other)
case other
when Note
if part_of_discussion?
in_reply_to?(other.noteable) && in_reply_to?(other.to_discussion)
else
in_reply_to?(other.noteable)
end
when Discussion
self.discussion_id == other.id
when Noteable
self.noteable == other
else
false
end
end
|
#issuable_ability_name ⇒ Object
776
777
778
|
# File 'app/models/note.rb', line 776
def issuable_ability_name
confidential? ? :read_internal_note : :read_note
end
|
#last_edited_at ⇒ Object
We used ‘last_edited_at` as an alias of `updated_at` before. This makes it compatible with the previous way without data migration.
461
462
463
|
# File 'app/models/note.rb', line 461
def last_edited_at
super || updated_at
end
|
#max_attachment_size ⇒ Object
337
338
339
|
# File 'app/models/note.rb', line 337
def max_attachment_size
Gitlab::CurrentSettings.max_attachment_size.megabytes.to_i
end
|
#mentioned_filtered_user_ids_for(references) ⇒ Object
749
750
751
752
753
754
755
756
757
758
|
# File 'app/models/note.rb', line 749
def mentioned_filtered_user_ids_for(references)
return super unless confidential?
user_ids = references.mentioned_user_ids.presence
return [] if user_ids.blank?
users = User.where(id: user_ids)
Ability.users_that_can_read_internal_notes(users, resource_parent).pluck(:id)
end
|
#mentioned_users(current_user = nil) ⇒ Object
741
742
743
744
745
746
747
|
# File 'app/models/note.rb', line 741
def mentioned_users(current_user = nil)
users = super
return users unless confidential?
Ability.users_that_can_read_internal_notes(users, resource_parent)
end
|
#merge_requests ⇒ Object
Notes on merge requests and commits can be traced back to one or several MRs. This method returns a relation if the note is for one of these types, or nil if it is a note on some other object.
408
409
410
411
412
413
414
|
# File 'app/models/note.rb', line 408
def merge_requests
if for_commit?
project.merge_requests.by_commit_sha(commit_id)
elsif for_merge_request?
MergeRequest.id_in(noteable_id)
end
end
|
#note ⇒ Object
762
763
764
765
766
|
# File 'app/models/note.rb', line 762
def note
return super unless system? && for_issue? && super&.match?(ISSUE_TASK_SYSTEM_NOTE_PATTERN)
super.sub!('task', 'checklist item')
end
|
#note_html ⇒ Object
770
771
772
773
774
|
# File 'app/models/note.rb', line 770
def note_html
return super unless system? && for_issue? && super&.match?(ISSUE_TASK_SYSTEM_NOTE_PATTERN)
super.sub!('task', 'checklist item')
end
|
#noteable ⇒ Object
override to return commits, which are not active record
417
418
419
420
421
422
423
424
425
|
# File 'app/models/note.rb', line 417
def noteable
return commit if for_commit?
super
rescue StandardError
nil
end
|
#noteable_ability_name ⇒ Object
489
490
491
492
493
494
495
496
497
498
499
|
# File 'app/models/note.rb', line 489
def noteable_ability_name
if for_snippet?
'snippet'
elsif for_alert_mangement_alert?
'alert_management_alert'
elsif for_vulnerability?
'security_resource'
else
noteable_type.demodulize.underscore
end
end
|
#noteable_author?(noteable) ⇒ Boolean
441
442
443
|
# File 'app/models/note.rb', line 441
def noteable_author?(noteable)
noteable.author == self.author
end
|
#noteable_type=(noteable_type) ⇒ Object
FIXME: Hack for polymorphic associations with STI
For more information visit http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations
429
430
431
|
# File 'app/models/note.rb', line 429
def noteable_type=(noteable_type)
super(noteable_type.to_s.classify.constantize.base_class.to_s)
end
|
#notify_after_create ⇒ Object
633
634
635
|
# File 'app/models/note.rb', line 633
def notify_after_create
noteable&.after_note_created(self)
end
|
#notify_after_destroy ⇒ Object
637
638
639
|
# File 'app/models/note.rb', line 637
def notify_after_destroy
noteable&.after_note_destroyed(self)
end
|
#parent_user ⇒ Object
665
666
667
|
# File 'app/models/note.rb', line 665
def parent_user
noteable.author if for_personal_snippet?
end
|
#part_of_discussion? ⇒ Boolean
548
549
550
|
# File 'app/models/note.rb', line 548
def part_of_discussion?
!to_discussion.individual_note?
end
|
#post_processed_cache_key ⇒ Object
673
674
675
676
677
678
679
|
# File 'app/models/note.rb', line 673
def post_processed_cache_key
cache_key_items = [cache_key, author&.cache_key]
cache_key_items << project.team.human_max_access(author&.id) if author.present?
cache_key_items << Digest::SHA1.hexdigest(redacted_note_html) if redacted_note_html.present?
cache_key_items.join(':')
end
|
#project_name ⇒ Object
445
446
447
|
# File 'app/models/note.rb', line 445
def project_name
project&.name
end
|
#references ⇒ Object
569
570
571
572
573
574
575
576
577
|
# File 'app/models/note.rb', line 569
def references
refs = [noteable]
if part_of_discussion?
refs += discussion.notes.take_while { |n| n.id < id }
end
refs
end
|
#resource_parent ⇒ Object
649
650
651
|
# File 'app/models/note.rb', line 649
def resource_parent
project
end
|
#retrieve_upload(_identifier, paths) ⇒ Object
645
646
647
|
# File 'app/models/note.rb', line 645
def retrieve_upload(_identifier, paths)
Upload.find_by(model: self, path: paths)
end
|
#show_outdated_changes? ⇒ Boolean
697
698
699
700
701
702
703
704
|
# File 'app/models/note.rb', line 697
def show_outdated_changes?
return false unless for_merge_request?
return false unless system?
return false if change_position&.on_file?
return false unless change_position&.line_range
change_position.line_range["end"] || change_position.line_range["start"]
end
|
#skip_notification? ⇒ Boolean
669
670
671
|
# File 'app/models/note.rb', line 669
def skip_notification?
review.present? || !author.can_trigger_notifications?
end
|
#skip_project_check? ⇒ Boolean
397
398
399
|
# File 'app/models/note.rb', line 397
def skip_project_check?
!for_project_noteable?
end
|
#start_of_discussion? ⇒ Boolean
544
545
546
|
# File 'app/models/note.rb', line 544
def start_of_discussion?
discussion.first_note == self
end
|
#supports_suggestion? ⇒ Boolean
345
346
347
|
# File 'app/models/note.rb', line 345
def supports_suggestion?
false
end
|
#system_note_visible_for?(user) ⇒ Boolean
659
660
661
662
663
|
# File 'app/models/note.rb', line 659
def system_note_visible_for?(user)
return true unless system?
system_note_viewable_by?(user) && all_referenced_mentionables_allowed?(user)
end
|
#system_note_with_references? ⇒ Boolean
rubocop: disable CodeReuse/ServiceClass
318
319
320
321
322
323
324
325
326
|
# File 'app/models/note.rb', line 318
def system_note_with_references?
return unless system?
if force_cross_reference_regex_check?
matches_cross_reference_regex?
else
::SystemNotes::IssuablesService.cross_reference?(note)
end
end
|
#to_discussion(noteable = nil) ⇒ Object
Returns a discussion containing just this note. This method exists as an alternative to ‘#discussion` to use when the methods we intend to call on the Discussion object don’t require it to have all of its notes, and just depend on the first note or the type of discussion. This saves us a DB query.
530
531
532
|
# File 'app/models/note.rb', line 530
def to_discussion(noteable = nil)
Discussion.build([self], noteable)
end
|
#touch(*args, **kwargs) ⇒ Object
598
599
600
601
602
603
604
605
606
607
|
# File 'app/models/note.rb', line 598
def touch(*args, **kwargs)
touch_noteable
super
end
|
#touch_noteable ⇒ Object
By default Rails will issue an “SELECT *” for the relation, which is overkill for just updating the timestamps. To work around this we manually touch the data so we can SELECT only the columns we need.
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
|
# File 'app/models/note.rb', line 612
def touch_noteable
return if for_commit?
assoc = association(:noteable)
noteable_object =
if assoc.loaded?
noteable
else
assoc.scope.select(:id, :updated_at).take
end
noteable_object&.touch
noteable_object
end
|
#trigger_note_subscription_create ⇒ Object
212
213
214
215
216
|
# File 'app/models/note.rb', line 212
def trigger_note_subscription_create
return unless trigger_note_subscription?
GraphqlTriggers.work_item_note_created(noteable.to_work_item_global_id, self)
end
|
#trigger_note_subscription_destroy ⇒ Object
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
# File 'app/models/note.rb', line 224
def trigger_note_subscription_destroy
return unless trigger_note_subscription?
deleted_note_data = {
id: self.id,
model_name: self.class.name,
discussion_id: self.discussion_id,
last_discussion_note: discussion.notes == [self]
}
GraphqlTriggers.work_item_note_deleted(noteable.to_work_item_global_id, deleted_note_data)
end
|
#trigger_note_subscription_update ⇒ Object
218
219
220
221
222
|
# File 'app/models/note.rb', line 218
def trigger_note_subscription_update
return unless trigger_note_subscription?
GraphqlTriggers.work_item_note_updated(noteable.to_work_item_global_id, self)
end
|
#user_mention_class ⇒ Object
682
683
684
685
686
|
# File 'app/models/note.rb', line 682
def user_mention_class
return if noteable.blank?
noteable.user_mention_class
end
|
#user_mention_identifier ⇒ Object
689
690
691
692
693
694
695
|
# File 'app/models/note.rb', line 689
def user_mention_identifier
return if noteable.blank?
noteable.user_mention_identifier.merge({
note_id: id
})
end
|
#user_mentions ⇒ Object
653
654
655
656
657
|
# File 'app/models/note.rb', line 653
def user_mentions
return Note.none unless noteable.present?
noteable.user_mentions.where(note: self)
end
|