diff options
author | Kushal Pandya <kushalspandya@gmail.com> | 2017-04-06 21:12:16 +0000 |
---|---|---|
committer | Kushal Pandya <kushalspandya@gmail.com> | 2017-04-06 21:12:16 +0000 |
commit | 8a5ca1121b090fe813144adf4428e7cb656b65d3 (patch) | |
tree | 3e6777ed81c3c08bdd4abba0d00826c68e51cba9 /app/models/concerns/routable.rb | |
parent | 26a672dabc6b5217a58a2ec9b3c88e869c87c6dd (diff) | |
parent | 69bf7bfa7b1ff33a66e8b4531ce2302cebf6678b (diff) | |
download | gitlab-ce-8a5ca1121b090fe813144adf4428e7cb656b65d3.tar.gz |
Merge branch 'master' into '18471-restrict-tag-pushes-protected-tags'
# Conflicts:
# spec/lib/gitlab/import_export/all_models.yml
Diffstat (limited to 'app/models/concerns/routable.rb')
-rw-r--r-- | app/models/concerns/routable.rb | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 529fb5ce988..aca99feee53 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -83,6 +83,74 @@ module Routable AND members.source_type = r2.source_type"). where('members.user_id = ?', user_id) end + + # Builds a relation to find multiple objects that are nested under user + # membership. Includes the parent, as opposed to `#member_descendants` + # which only includes the descendants. + # + # Usage: + # + # Klass.member_self_and_descendants(1) + # + # Returns an ActiveRecord::Relation. + def member_self_and_descendants(user_id) + joins(:route). + joins("INNER JOIN routes r2 ON routes.path LIKE CONCAT(r2.path, '/%') + OR routes.path = r2.path + INNER JOIN members ON members.source_id = r2.source_id + AND members.source_type = r2.source_type"). + where('members.user_id = ?', user_id) + end + + # Returns all objects in a hierarchy, where any node in the hierarchy is + # under the user membership. + # + # Usage: + # + # Klass.member_hierarchy(1) + # + # Examples: + # + # Given the following group tree... + # + # _______group_1_______ + # | | + # | | + # nested_group_1 nested_group_2 + # | | + # | | + # nested_group_1_1 nested_group_2_1 + # + # + # ... the following results are returned: + # + # * the user is a member of group 1 + # => 'group_1', + # 'nested_group_1', nested_group_1_1', + # 'nested_group_2', 'nested_group_2_1' + # + # * the user is a member of nested_group_2 + # => 'group1', + # 'nested_group_2', 'nested_group_2_1' + # + # * the user is a member of nested_group_2_1 + # => 'group1', + # 'nested_group_2', 'nested_group_2_1' + # + # Returns an ActiveRecord::Relation. + def member_hierarchy(user_id) + paths = member_self_and_descendants(user_id).pluck('routes.path') + + return none if paths.empty? + + wheres = paths.map do |path| + "#{connection.quote(path)} = routes.path + OR + #{connection.quote(path)} LIKE CONCAT(routes.path, '/%')" + end + + joins(:route).where(wheres.join(' OR ')) + end end def full_name |