diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2015-11-18 14:21:06 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2015-11-18 15:05:45 +0300 |
commit | fbcf3bd3fc94a39982e2bb11aa61ac014326e53a (patch) | |
tree | 3c5106989bfbc085f665c4c87433e592085c049d /app/finders/personal_projects_finder.rb | |
parent | 2110247f83440f4a1044b999ff0f2630bd36e969 (diff) |
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/personal_projects_finder.rb')
-rw-r--r-- | app/finders/personal_projects_finder.rb | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/app/finders/personal_projects_finder.rb b/app/finders/personal_projects_finder.rb new file mode 100644 index 00000000000..7c039573614 --- /dev/null +++ b/app/finders/personal_projects_finder.rb @@ -0,0 +1,37 @@ +class PersonalProjectsFinder + def initialize(user) + @user = user + end + + # Finds the projects belonging to the user in "@user", limited to either + # public projects or projects visible to the given user. + # + # current_user - When given the list of 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.personal_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.personal_projects.public_only + end +end |