diff options
author | Wei-Meng Lee <wlee@gitlab.com> | 2019-04-26 23:17:06 +0800 |
---|---|---|
committer | Wei-Meng Lee <wlee@gitlab.com> | 2019-05-31 20:49:27 +0800 |
commit | 03e08ab775312b92440caadc06a88b6f6805bc18 (patch) | |
tree | 668f476b3207c62488267f72e0205b7b97fca67d /app | |
parent | 31775ad83aa35fa29e66d3322e6bdf921f4e1792 (diff) | |
download | gitlab-ce-03e08ab775312b92440caadc06a88b6f6805bc18.tar.gz |
Guarantee order of notification settings
Diffstat (limited to 'app')
-rw-r--r-- | app/mailers/notify.rb | 12 | ||||
-rw-r--r-- | app/models/group.rb | 10 | ||||
-rw-r--r-- | app/models/namespace.rb | 4 |
3 files changed, 12 insertions, 14 deletions
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 11738afecb9..f78be3882d6 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -82,16 +82,8 @@ class Notify < BaseMailer group_notification_email = nil if notification_group - # Get notification group's and ancestors' notification settings - group_ids = notification_group.self_and_ancestors_ids - notification_settings = notification_group.notification_settings.where(user: @current_user) # rubocop: disable CodeReuse/ActiveRecord - - # Exploit notification_group.self_and_ancestors_ids being ordered from - # most nested to least nested to iterate through group ancestors - group_ids.each do |group_id| - group_notification_email = notification_settings.find { |ns| ns.source_id == group_id }&.notification_email - break if group_notification_email.present? - end + notification_settings = notification_group.notification_settings(hierarchy_order: :asc).where(user: @current_user) # rubocop: disable CodeReuse/ActiveRecord + group_notification_email = notification_settings.find { |n| n.notification_email.present? }&.notification_email end # Return group-specific email address if present, otherwise return global diff --git a/app/models/group.rb b/app/models/group.rb index 53331a19776..25d246f64e7 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -126,10 +126,16 @@ class Group < Namespace # Overrides notification_settings has_many association # This allows to apply notification settings from parent groups # to child groups and projects. - def notification_settings + def notification_settings(hierarchy_order: nil) source_type = self.class.base_class.name + settings = NotificationSetting.where(source_type: source_type, source_id: self_and_ancestors_ids) - NotificationSetting.where(source_type: source_type, source_id: self_and_ancestors_ids) + return settings unless hierarchy_order && self_and_ancestors_ids.length > 1 + + settings + .joins("LEFT JOIN (#{self_and_ancestors(hierarchy_order: hierarchy_order).to_sql}) AS ordered_groups ON notification_settings.source_id = ordered_groups.id") + .select('notification_settings.*, ordered_groups.depth AS depth') + .order("ordered_groups.depth #{hierarchy_order}") end def to_reference(_from = nil, full: nil) diff --git a/app/models/namespace.rb b/app/models/namespace.rb index f7c31890198..3c270c7396a 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -206,12 +206,12 @@ class Namespace < ApplicationRecord .ancestors(upto: top, hierarchy_order: hierarchy_order) end - def self_and_ancestors + def self_and_ancestors(hierarchy_order: nil) return self.class.where(id: id) unless parent_id Gitlab::ObjectHierarchy .new(self.class.where(id: id)) - .base_and_ancestors + .base_and_ancestors(hierarchy_order: hierarchy_order) end # Returns all the descendants of the current namespace. |