2020-03-13 15:44:24 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module API
|
|
|
|
module Entities
|
|
|
|
class BasicProjectDetails < Entities::ProjectIdentity
|
|
|
|
include ::API::ProjectsRelationBuilder
|
2021-09-04 01:27:46 +05:30
|
|
|
include Gitlab::Utils::StrongMemoize
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2021-09-30 23:02:18 +05:30
|
|
|
expose :default_branch_or_main, as: :default_branch, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) }
|
2020-03-13 15:44:24 +05:30
|
|
|
# Avoids an N+1 query: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770
|
2021-09-04 01:27:46 +05:30
|
|
|
|
|
|
|
expose :topic_names, as: :tag_list
|
|
|
|
expose :topic_names, as: :topics
|
2020-03-13 15:44:24 +05:30
|
|
|
|
|
|
|
expose :ssh_url_to_repo, :http_url_to_repo, :web_url, :readme_url
|
|
|
|
|
|
|
|
expose :license_url, if: :license do |project|
|
|
|
|
license = project.repository.license_blob
|
|
|
|
|
|
|
|
if license
|
|
|
|
Gitlab::Routing.url_helpers.project_blob_url(project, File.join(project.default_branch, license.path))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
expose :license, with: 'API::Entities::LicenseBasic', if: :license do |project|
|
|
|
|
project.repository.license
|
|
|
|
end
|
|
|
|
|
|
|
|
expose :avatar_url do |project, options|
|
|
|
|
project.avatar_url(only_path: false)
|
|
|
|
end
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
expose :forks_count
|
|
|
|
expose :star_count
|
2020-03-13 15:44:24 +05:30
|
|
|
expose :last_activity_at
|
|
|
|
expose :namespace, using: 'API::Entities::NamespaceBasic'
|
|
|
|
expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes
|
|
|
|
|
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
|
|
|
def self.preload_relation(projects_relation, options = {})
|
2021-09-04 01:27:46 +05:30
|
|
|
# Preloading topics, should be done with using only `:topics`,
|
2021-11-18 22:05:49 +05:30
|
|
|
# as `:topics` are defined as: `has_many :topics, through: :project_topics`
|
2021-09-04 01:27:46 +05:30
|
|
|
# N+1 is solved then by using `subject.topics.map(&:name)`
|
2020-03-13 15:44:24 +05:30
|
|
|
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20555
|
|
|
|
projects_relation.preload(:project_feature, :route)
|
2021-11-18 22:05:49 +05:30
|
|
|
.preload(:import_state, :topics)
|
2020-03-13 15:44:24 +05:30
|
|
|
.preload(:auto_devops)
|
|
|
|
.preload(namespace: [:route, :owner])
|
|
|
|
end
|
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2021-09-04 01:27:46 +05:30
|
|
|
|
2021-11-11 11:23:49 +05:30
|
|
|
def self.execute_batch_counting(projects_relation)
|
|
|
|
# Call the count methods on every project, so the BatchLoader would load them all at
|
|
|
|
# once when the entities are rendered
|
|
|
|
projects_relation.each(&:forks_count)
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
private
|
|
|
|
|
|
|
|
alias_method :project, :object
|
|
|
|
|
|
|
|
def topic_names
|
|
|
|
# Topics is a preloaded association. If we perform then sorting
|
|
|
|
# through the database, it will trigger a new query, ending up
|
|
|
|
# in an N+1 if we have several projects
|
|
|
|
strong_memoize(:topic_names) do
|
|
|
|
project.topics.pluck(:name).sort # rubocop:disable CodeReuse/ActiveRecord
|
|
|
|
end
|
|
|
|
end
|
2020-03-13 15:44:24 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|