From 5ea4e34f4755e9a15503a6f16fd1574dc7864b23 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Thu, 9 Mar 2017 20:27:14 +0100 Subject: add method to get a full routable hierarchy --- app/models/concerns/routable.rb | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'app/models/concerns') diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 529fb5ce988..9b8970a1f38 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? + + leaf_paths = paths.group_by(&:length).flat_map(&:last) + + wheres = leaf_paths.map do |leaf_path| + "#{connection.quote(leaf_path)} LIKE CONCAT(routes.path, '%')" + end + + joins(:route).where(wheres.join(' OR ')) + end end def full_name -- cgit v1.2.1 From 20575859b1bf431421427d52c4ac5a33cf662df6 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Thu, 9 Mar 2017 20:38:13 +0100 Subject: check all groups for 2fa requirement --- app/models/concerns/routable.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'app/models/concerns') diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 9b8970a1f38..b907e421743 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -143,10 +143,8 @@ module Routable return none if paths.empty? - leaf_paths = paths.group_by(&:length).flat_map(&:last) - - wheres = leaf_paths.map do |leaf_path| - "#{connection.quote(leaf_path)} LIKE CONCAT(routes.path, '%')" + wheres = paths.map do |path| + "#{connection.quote(path)} LIKE CONCAT(routes.path, '%')" end joins(:route).where(wheres.join(' OR ')) -- cgit v1.2.1 From 63e61cfd83bdc03d5c0657b5f93c3236d6a2d987 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Wed, 15 Mar 2017 13:45:28 +0100 Subject: use more explicit and explanatory sql statement --- app/models/concerns/routable.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'app/models/concerns') diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index b907e421743..aca99feee53 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -144,7 +144,9 @@ module Routable return none if paths.empty? wheres = paths.map do |path| - "#{connection.quote(path)} LIKE CONCAT(routes.path, '%')" + "#{connection.quote(path)} = routes.path + OR + #{connection.quote(path)} LIKE CONCAT(routes.path, '/%')" end joins(:route).where(wheres.join(' OR ')) -- cgit v1.2.1 From 3e1a1242c67781fb52940433c5ad1bbefd346216 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Thu, 6 Apr 2017 15:36:36 +0530 Subject: Move a user's award emoji to the ghost user ... when the user is destroyed. 1. Normally, for a given awardable and award emoji name, a user is only allowed to create a single award emoji. 2. This validation needs to be removed for ghost users, since: - User A and User B have created award emoji - with the same name and against the same awardable - User A is deleted. Their award emoji is moved to the ghost user - User B is deleted. Their award emoji needs to be moved to the ghost user. However, this breaks the uniqueness validation, since the ghost user is only allowed to have one award emoji of a given name for a given awardable --- app/models/concerns/ghost_user.rb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/models/concerns/ghost_user.rb (limited to 'app/models/concerns') diff --git a/app/models/concerns/ghost_user.rb b/app/models/concerns/ghost_user.rb new file mode 100644 index 00000000000..da696127a80 --- /dev/null +++ b/app/models/concerns/ghost_user.rb @@ -0,0 +1,7 @@ +module GhostUser + extend ActiveSupport::Concern + + def ghost_user? + user && user.ghost? + end +end -- cgit v1.2.1