summaryrefslogtreecommitdiff
path: root/app/finders/contributed_projects_finder.rb
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2015-11-18 12:21:06 +0100
committerYorick Peterse <yorickpeterse@gmail.com>2015-11-18 13:05:45 +0100
commitfbcf3bd3fc94a39982e2bb11aa61ac014326e53a (patch)
tree3c5106989bfbc085f665c4c87433e592085c049d /app/finders/contributed_projects_finder.rb
parent2110247f83440f4a1044b999ff0f2630bd36e969 (diff)
downloadgitlab-ce-fbcf3bd3fc94a39982e2bb11aa61ac014326e53a.tar.gz
Refactor ProjectsFinder to not pluck IDs
This class now uses a UNION (when needed) instead of plucking tens of thousands of project IDs into memory. The tests have also been re-written to ensure all different use cases are tested properly (assuming I didn't forget any cases). The finder has also been broken up into 3 different finder classes: * ContributedProjectsFinder: class for getting the projects a user contributed to. * PersonalProjectsFinder: class for getting the personal projects of a user. * ProjectsFinder: class for getting generic projects visible to a given user. Previously a lot of the logic of these finders was handled directly in the users controller.
Diffstat (limited to 'app/finders/contributed_projects_finder.rb')
-rw-r--r--app/finders/contributed_projects_finder.rb37
1 files changed, 37 insertions, 0 deletions
diff --git a/app/finders/contributed_projects_finder.rb b/app/finders/contributed_projects_finder.rb
new file mode 100644
index 00000000000..0209649b017
--- /dev/null
+++ b/app/finders/contributed_projects_finder.rb
@@ -0,0 +1,37 @@
+class ContributedProjectsFinder
+ def initialize(user)
+ @user = user
+ end
+
+ # Finds the projects "@user" contributed to, limited to either public projects
+ # or projects visible to the given user.
+ #
+ # current_user - When given the list of the projects is limited to those only
+ # visible by this user.
+ #
+ # Returns an ActiveRecord::Relation.
+ def execute(current_user = nil)
+ if current_user
+ relation = projects_visible_to_user(current_user)
+ else
+ relation = public_projects
+ end
+
+ relation.includes(:namespace).order_id_desc
+ end
+
+ private
+
+ def projects_visible_to_user(current_user)
+ authorized = @user.contributed_projects.visible_to_user(current_user)
+
+ union = Gitlab::SQL::Union.
+ new([authorized.select(:id), public_projects.select(:id)])
+
+ Project.where("projects.id IN (#{union.to_sql})")
+ end
+
+ def public_projects
+ @user.contributed_projects.public_only
+ end
+end