gitlab-org--gitlab-foss/app/models/notification_setting.rb
Sean McGivern e94c1028c1 Deserialise existing custom notification settings
Create a post-deployment migration to update all existing notification settings
with at least one custom level enabled to the new format. Also handle the same
conversion when updating settings, to catch any stragglers.
2017-06-15 15:15:13 +01:00

95 lines
2.5 KiB
Ruby

class NotificationSetting < ActiveRecord::Base
enum level: { global: 3, watch: 2, mention: 4, participating: 1, disabled: 0, custom: 5 }
default_value_for :level, NotificationSetting.levels[:global]
belongs_to :user
belongs_to :source, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
belongs_to :project, foreign_key: 'source_id'
validates :user, presence: true
validates :level, presence: true
validates :user_id, uniqueness: { scope: [:source_type, :source_id],
message: "already exists in source",
allow_nil: true }
scope :for_groups, -> { where(source_type: 'Namespace') }
# Exclude projects not included by the Project model's default scope (those that are
# pending delete).
#
scope :for_projects, -> do
includes(:project).references(:projects).where(source_type: 'Project').where.not(projects: { id: nil })
end
EMAIL_EVENTS = [
:new_note,
:new_issue,
:reopen_issue,
:close_issue,
:reassign_issue,
:new_merge_request,
:reopen_merge_request,
:close_merge_request,
:reassign_merge_request,
:merge_merge_request,
:failed_pipeline,
:success_pipeline
].freeze
EXCLUDED_WATCHER_EVENTS = [
:success_pipeline
].freeze
store :events, coder: JSON
before_save :convert_events
def self.find_or_create_for(source)
setting = find_or_initialize_by(source: source)
unless setting.persisted?
setting.save
end
setting
end
# 1. Check if this event has a value stored in its database column.
# 2. If it does, return that value.
# 3. If it doesn't (the value is nil), return the value from the serialized
# JSON hash in `events`.
(EMAIL_EVENTS - [:failed_pipeline]).each do |event|
define_method(event) do
bool = super()
bool.nil? ? !!events[event] : bool
end
alias_method :"#{event}?", event
end
# Allow people to receive failed pipeline notifications if they already have
# custom notifications enabled, as these are more like mentions than the other
# custom settings.
def failed_pipeline
bool = super
bool = events[:failed_pipeline] if bool.nil?
bool.nil? || bool
end
alias_method :failed_pipeline?, :failed_pipeline
def event_enabled?(event)
respond_to?(event) && public_send(event)
end
def convert_events
return if events_before_type_cast.nil?
EMAIL_EVENTS.each do |event|
write_attribute(event, public_send(event))
end
write_attribute(:events, nil)
end
end