diff options
-rw-r--r-- | app/models/commit.rb | 17 | ||||
-rw-r--r-- | app/models/concerns/issuable.rb | 18 | ||||
-rw-r--r-- | app/models/concerns/participable.rb | 42 | ||||
-rw-r--r-- | app/models/note.rb | 2 | ||||
-rw-r--r-- | app/models/snippet.rb | 15 |
5 files changed, 51 insertions, 43 deletions
diff --git a/app/models/commit.rb b/app/models/commit.rb index 1985793c600..be5a118bfec 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -3,8 +3,10 @@ class Commit include StaticModel extend ActiveModel::Naming include Mentionable + include Participable attr_mentionable :safe_message + participant :author, :committer, :notes, :mentioned_users attr_accessor :project @@ -137,21 +139,6 @@ class Commit User.find_for_commit(committer_email, committer_name) end - def participants(current_user = nil) - users = [] - users << author - users << committer - - users.push *self.mentioned_users(current_user) - - notes.each do |note| - users << note.author - users.push *note.mentioned_users(current_user) - end - - users.uniq - end - def notes project.notes.for_commit_id(self.id) end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index a21d9bdfe8a..97846b06d72 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -7,6 +7,7 @@ module Issuable extend ActiveSupport::Concern include Mentionable + include Participable included do belongs_to :author, class_name: "User" @@ -45,6 +46,7 @@ module Issuable prefix: true attr_mentionable :title, :description + participant :author, :assignee, :notes, :mentioned_users end module ClassMethods @@ -117,22 +119,6 @@ module Issuable upvotes + downvotes end - # Return all users participating on the discussion - def participants(current_user = self.author) - users = [] - users << author - users << assignee if is_assigned? - - users.push *self.mentioned_users(current_user) - - notes.each do |note| - users << note.author - users.push *note.mentioned_users(current_user) - end - - users.uniq - end - def subscribed?(user) subscription = subscriptions.find_by_user_id(user.id) diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb new file mode 100644 index 00000000000..d78810f2eab --- /dev/null +++ b/app/models/concerns/participable.rb @@ -0,0 +1,42 @@ +module Participable + extend ActiveSupport::Concern + + module ClassMethods + def participant(*attrs) + participant_attrs.concat(attrs.map(&:to_s)) + end + + def participant_attrs + @participant_attrs ||= [] + end + end + + def participants(current_user = self.author) + self.class.participant_attrs.flat_map do |attr| + meth = method(attr) + + value = + if meth.arity == 1 + meth.call(current_user) + else + meth.call + end + + participants_for(value, current_user) + end.compact.uniq + end + + private + def participants_for(value, current_user = nil) + case value + when User + [value] + when Array + value.flat_map { |v| participants_for(v, current_user) } + when Participable + value.participants(current_user) + when Mentionable + value.mentioned_users(current_user) + end + end +end diff --git a/app/models/note.rb b/app/models/note.rb index 26739426a88..e1cd971132b 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -23,10 +23,12 @@ require 'file_size_validator' class Note < ActiveRecord::Base include Mentionable include Gitlab::CurrentSettings + include Participable default_value_for :system, false attr_mentionable :note + participant :author, :mentioned_users belongs_to :project belongs_to :noteable, polymorphic: true diff --git a/app/models/snippet.rb b/app/models/snippet.rb index c11c28805eb..d2af26539b6 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -19,6 +19,7 @@ class Snippet < ActiveRecord::Base include Sortable include Linguist::BlobHelper include Gitlab::VisibilityLevel + include Participable default_value_for :visibility_level, Snippet::PRIVATE @@ -47,6 +48,8 @@ class Snippet < ActiveRecord::Base scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) } scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) } + participant :author, :notes + def self.content_types [ ".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java", @@ -87,18 +90,6 @@ class Snippet < ActiveRecord::Base visibility_level end - def participants(current_user = self.author) - users = [] - users << author - - notes.each do |note| - users << note.author - users.push *note.mentioned_users(current_user) - end - - users.uniq - end - class << self def search(query) where('(title LIKE :query OR file_name LIKE :query)', query: "%#{query}%") |