Refactored /projects and /user/:user_id/projects endpoints
This commit is contained in:
parent
c85f9c5b1d
commit
58c5b463ff
4 changed files with 77 additions and 25 deletions
|
@ -94,7 +94,13 @@ module API
|
||||||
project.avatar_url(only_path: false)
|
project.avatar_url(only_path: false)
|
||||||
end
|
end
|
||||||
expose :star_count, :forks_count
|
expose :star_count, :forks_count
|
||||||
expose :last_activity_at
|
expose :created_at, :last_activity_at
|
||||||
|
|
||||||
|
def self.preload_relation(projects_relation)
|
||||||
|
projects_relation.preload(:project_feature, :route)
|
||||||
|
.preload(namespace: [:route, :owner],
|
||||||
|
tags: :taggings)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Project < BasicProjectDetails
|
class Project < BasicProjectDetails
|
||||||
|
@ -128,6 +134,18 @@ module API
|
||||||
expose :members do |project|
|
expose :members do |project|
|
||||||
expose_url(api_v4_projects_members_path(id: project.id))
|
expose_url(api_v4_projects_members_path(id: project.id))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.preload_relation(projects_relation)
|
||||||
|
super(projects_relation).preload(:group)
|
||||||
|
.preload(project_group_links: :group,
|
||||||
|
fork_network: :root_project,
|
||||||
|
forked_project_link: :forked_from_project,
|
||||||
|
forked_from_project: [:route, :forks, namespace: :route, tags: :taggings])
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.forks_counting_projects(projects_relation)
|
||||||
|
projects_relation + projects_relation.map(&:forked_from_project).compact
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :archived?, as: :archived
|
expose :archived?, as: :archived
|
||||||
|
@ -635,9 +653,16 @@ module API
|
||||||
class MemberAccess < Grape::Entity
|
class MemberAccess < Grape::Entity
|
||||||
expose :access_level
|
expose :access_level
|
||||||
expose :notification_level do |member, options|
|
expose :notification_level do |member, options|
|
||||||
if member.notification_setting
|
notification = member_notification_setting(member)
|
||||||
::NotificationSetting.levels[member.notification_setting.level]
|
::NotificationSetting.levels[notification.level] if notification
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def member_notification_setting(member)
|
||||||
|
member.user.notification_settings.select do |notification|
|
||||||
|
notification.source_id == member.source_id && notification.source_type == member.source_type
|
||||||
|
end.last
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -680,18 +705,21 @@ module API
|
||||||
expose :permissions do
|
expose :permissions do
|
||||||
expose :project_access, using: Entities::ProjectAccess do |project, options|
|
expose :project_access, using: Entities::ProjectAccess do |project, options|
|
||||||
if options.key?(:project_members)
|
if options.key?(:project_members)
|
||||||
(options[:project_members] || []).find { |member| member.source_id == project.id }
|
(options[:project_members] || []).select { |member| member.source_id == project.id }.last
|
||||||
else
|
elsif project.project_members.any?
|
||||||
project.project_members.find_by(user_id: options[:current_user].id)
|
# This is not the bet option to search in a CollectionProxy, but if
|
||||||
|
# we use find_by we will perform another query, even if the association
|
||||||
|
# is loaded
|
||||||
|
project.project_members.select { |project_member| project_member.user_id == options[:current_user].id }.last
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :group_access, using: Entities::GroupAccess do |project, options|
|
expose :group_access, using: Entities::GroupAccess do |project, options|
|
||||||
if project.group
|
if project.group
|
||||||
if options.key?(:group_members)
|
if options.key?(:group_members)
|
||||||
(options[:group_members] || []).find { |member| member.source_id == project.namespace_id }
|
(options[:group_members] || []).select { |member| member.source_id == project.namespace_id }.last
|
||||||
else
|
elsif project.group.group_members.any?
|
||||||
project.group.group_members.find_by(user_id: options[:current_user].id)
|
project.group.group_members.select { |group_member| group_member.user_id == options[:current_user].id }.last
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,19 +55,8 @@ module API
|
||||||
def find_group_projects(params)
|
def find_group_projects(params)
|
||||||
group = find_group!(params[:id])
|
group = find_group!(params[:id])
|
||||||
projects = GroupProjectsFinder.new(group: group, current_user: current_user, params: project_finder_params).execute
|
projects = GroupProjectsFinder.new(group: group, current_user: current_user, params: project_finder_params).execute
|
||||||
projects = projects.preload(:project_feature, :route, :group)
|
|
||||||
.preload(namespace: [:route, :owner],
|
|
||||||
tags: :taggings,
|
|
||||||
project_group_links: :group,
|
|
||||||
fork_network: :root_project,
|
|
||||||
forked_project_link: :forked_from_project,
|
|
||||||
forked_from_project: [:route, :forks, namespace: :route, tags: :taggings])
|
|
||||||
projects = reorder_projects(projects)
|
projects = reorder_projects(projects)
|
||||||
projects = paginate(projects)
|
paginate(projects)
|
||||||
projects_with_forks = projects + projects.map(&:forked_from_project).compact
|
|
||||||
::Projects::BatchForksCountService.new(projects_with_forks).refresh_cache
|
|
||||||
::Projects::BatchOpenIssuesCountService.new(projects).refresh_cache
|
|
||||||
projects
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def present_groups(params, groups)
|
def present_groups(params, groups)
|
||||||
|
@ -190,7 +179,8 @@ module API
|
||||||
get ":id/projects" do
|
get ":id/projects" do
|
||||||
projects = find_group_projects(params)
|
projects = find_group_projects(params)
|
||||||
entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project
|
entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project
|
||||||
present projects, with: entity, current_user: current_user
|
|
||||||
|
present entity.prepare_relation(projects), with: entity, current_user: current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
desc 'Get a list of subgroups in this group.' do
|
desc 'Get a list of subgroups in this group.' do
|
||||||
|
|
|
@ -79,9 +79,9 @@ module API
|
||||||
projects = projects.with_statistics if params[:statistics]
|
projects = projects.with_statistics if params[:statistics]
|
||||||
projects = projects.with_issues_enabled if params[:with_issues_enabled]
|
projects = projects.with_issues_enabled if params[:with_issues_enabled]
|
||||||
projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled]
|
projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled]
|
||||||
|
projects = paginate(projects)
|
||||||
|
|
||||||
if current_user
|
if current_user
|
||||||
projects = projects.includes(:route, :taggings, namespace: :route)
|
|
||||||
project_members = current_user.project_members
|
project_members = current_user.project_members
|
||||||
group_members = current_user.group_members
|
group_members = current_user.group_members
|
||||||
end
|
end
|
||||||
|
@ -95,7 +95,7 @@ module API
|
||||||
)
|
)
|
||||||
options[:with] = Entities::BasicProjectDetails if params[:simple]
|
options[:with] = Entities::BasicProjectDetails if params[:simple]
|
||||||
|
|
||||||
present paginate(projects), options
|
present options[:with].prepare_relation(projects), options
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
34
lib/api/projects_relation_builder.rb
Normal file
34
lib/api/projects_relation_builder.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
module API
|
||||||
|
module ProjectsRelationBuilder
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def prepare_relation(relation)
|
||||||
|
relation = preload_relation(relation)
|
||||||
|
execute_batch_counting(relation)
|
||||||
|
relation
|
||||||
|
end
|
||||||
|
|
||||||
|
def preload_relation(relation)
|
||||||
|
raise NotImplementedError, 'self.preload_relation method must be defined and return a relation'
|
||||||
|
end
|
||||||
|
|
||||||
|
def forks_counting_projects(projects_relation)
|
||||||
|
projects_relation
|
||||||
|
end
|
||||||
|
|
||||||
|
def batch_forks_counting(projects_relation)
|
||||||
|
::Projects::BatchForksCountService.new(forks_counting_projects(projects_relation)).refresh_cache
|
||||||
|
end
|
||||||
|
|
||||||
|
def batch_open_issues_counting(projects_relation)
|
||||||
|
::Projects::BatchOpenIssuesCountService.new(projects_relation).refresh_cache
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_batch_counting(projects_relation)
|
||||||
|
batch_forks_counting(projects_relation)
|
||||||
|
batch_open_issues_counting(projects_relation)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue