summaryrefslogtreecommitdiff
path: root/app/models/project.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/project.rb')
-rw-r--r--app/models/project.rb17
1 files changed, 13 insertions, 4 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index 5c6088d120f..2e126bd50c1 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -321,7 +321,10 @@ class Project < ActiveRecord::Base
# the query, e.g. to apply .with_feature_available_for_user on top of it.
# This is useful for performance as we can stick those additional filters
# at the bottom of e.g. the UNION.
- def self.public_or_visible_to_user(user = nil, &block)
+ #
+ # Optionally, turning `use_conditions_only` off leads to returning a
+ # relation using #from instead of #where.
+ def self.public_or_visible_to_user(user = nil, use_conditions_only: true, &block)
# If we don't get a block passed, use identity to avoid if/else repetitions
block = ->(part) { part } unless block_given?
@@ -344,9 +347,15 @@ class Project < ActiveRecord::Base
# We use a UNION here instead of OR clauses since this results in better
# performance.
- union = Gitlab::SQL::Union.new([authorized_projects.select('projects.id'), visible_projects.select('projects.id')])
- # TODO: from("(#{union.to_sql}) AS #{table_name}")
- where("projects.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
+ union_branches = [authorized_projects, visible_projects]
+
+ if use_conditions_only
+ union = Gitlab::SQL::Union.new(union_branches.map { |b| b.select('projects.id') })
+ where("projects.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
+ else
+ union = Gitlab::SQL::Union.new(union_branches)
+ from("(#{union.to_sql}) AS #{table_name}")
+ end
else
block.call(public_to_user)
end