debian-mirror-gitlab/app/models/concerns/participable.rb

76 lines
2 KiB
Ruby
Raw Normal View History

2015-09-11 14:41:01 +05:30
# == Participable concern
#
# Contains functionality related to objects that can have participants, such as
# an author, an assignee and people mentioned in its description or comments.
#
# Used by Issue, Note, MergeRequest, Snippet and Commit.
#
# Usage:
#
# class Issue < ActiveRecord::Base
# include Participable
#
# # ...
#
2015-10-24 18:46:33 +05:30
# participant :author, :assignee, :notes, ->(current_user) { mentioned_users(current_user) }
2015-09-11 14:41:01 +05:30
# end
#
# issue = Issue.last
# users = issue.participants
# # `users` will contain the issue's author, its assignee,
# # all users returned by its #mentioned_users method,
# # as well as all participants to all of the issue's notes,
# # since Note implements Participable as well.
#
module Participable
extend ActiveSupport::Concern
module ClassMethods
def participant(*attrs)
2015-10-24 18:46:33 +05:30
participant_attrs.concat(attrs)
2015-09-11 14:41:01 +05:30
end
def participant_attrs
@participant_attrs ||= []
end
end
# Be aware that this method makes a lot of sql queries.
# Save result into variable if you are going to reuse it inside same request
2015-10-24 18:46:33 +05:30
def participants(current_user = self.author, load_lazy_references: true)
2015-09-11 14:41:01 +05:30
participants = self.class.participant_attrs.flat_map do |attr|
value =
2015-10-24 18:46:33 +05:30
if attr.respond_to?(:call)
instance_exec(current_user, &attr)
2015-09-11 14:41:01 +05:30
else
2015-10-24 18:46:33 +05:30
send(attr)
2015-09-11 14:41:01 +05:30
end
2015-10-24 18:46:33 +05:30
participants_for(value, current_user)
2015-09-11 14:41:01 +05:30
end.compact.uniq
2015-10-24 18:46:33 +05:30
if load_lazy_references
participants = Gitlab::Markdown::ReferenceFilter::LazyReference.load(participants).uniq
2015-09-11 14:41:01 +05:30
participants.select! do |user|
user.can?(:read_project, project)
end
end
participants
end
private
2015-10-24 18:46:33 +05:30
def participants_for(value, current_user = nil)
2015-09-11 14:41:01 +05:30
case value
2015-10-24 18:46:33 +05:30
when User, Gitlab::Markdown::ReferenceFilter::LazyReference
2015-09-11 14:41:01 +05:30
[value]
when Enumerable, ActiveRecord::Relation
2015-10-24 18:46:33 +05:30
value.flat_map { |v| participants_for(v, current_user) }
2015-09-11 14:41:01 +05:30
when Participable
2015-10-24 18:46:33 +05:30
value.participants(current_user, load_lazy_references: false)
2015-09-11 14:41:01 +05:30
end
end
end