fix: Notification page breakages (#5236)
- Remove the cascading foreign key indexes - Add migration to clean up existing objects fixes: #4285
This commit is contained in:
parent
12b6fb211a
commit
74fdfffe08
23 changed files with 93 additions and 115 deletions
|
@ -183,3 +183,4 @@ AllCops:
|
||||||
- db/migrate/20200503151130_add_account_feature_flag.rb
|
- db/migrate/20200503151130_add_account_feature_flag.rb
|
||||||
- db/migrate/20200927135222_add_last_activity_at_to_conversation.rb
|
- db/migrate/20200927135222_add_last_activity_at_to_conversation.rb
|
||||||
- db/migrate/20210306170117_add_last_activity_at_to_contacts.rb
|
- db/migrate/20210306170117_add_last_activity_at_to_contacts.rb
|
||||||
|
- db/migrate/20220809104508_revert_cascading_indexes.rb
|
||||||
|
|
19
app/jobs/migration/remove_stale_notifications_job.rb
Normal file
19
app/jobs/migration/remove_stale_notifications_job.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Delete migration and spec after 2 consecutive releases.
|
||||||
|
class Migration::RemoveStaleNotificationsJob < ApplicationJob
|
||||||
|
queue_as :scheduled_jobs
|
||||||
|
|
||||||
|
def perform
|
||||||
|
remove_invalid_messages
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def remove_invalid_messages
|
||||||
|
deleted_ids = []
|
||||||
|
Message.distinct.pluck(:inbox_id).each_slice(1000) do |id_list|
|
||||||
|
deleted_ids << (id_list - Inbox.where(id: id_list).pluck(:id))
|
||||||
|
end
|
||||||
|
|
||||||
|
Message.where(inbox_id: deleted_ids.flatten).destroy_all
|
||||||
|
end
|
||||||
|
end
|
|
@ -55,7 +55,7 @@ class Account < ApplicationRecord
|
||||||
has_many :csat_survey_responses, dependent: :destroy_async
|
has_many :csat_survey_responses, dependent: :destroy_async
|
||||||
has_many :custom_attribute_definitions, dependent: :destroy_async
|
has_many :custom_attribute_definitions, dependent: :destroy_async
|
||||||
has_many :custom_filters, dependent: :destroy_async
|
has_many :custom_filters, dependent: :destroy_async
|
||||||
has_many :dashboard_apps, dependent: :destroy
|
has_many :dashboard_apps, dependent: :destroy_async
|
||||||
has_many :data_imports, dependent: :destroy_async
|
has_many :data_imports, dependent: :destroy_async
|
||||||
has_many :email_channels, dependent: :destroy_async, class_name: '::Channel::Email'
|
has_many :email_channels, dependent: :destroy_async, class_name: '::Channel::Email'
|
||||||
has_many :facebook_pages, dependent: :destroy_async, class_name: '::Channel::FacebookPage'
|
has_many :facebook_pages, dependent: :destroy_async, class_name: '::Channel::FacebookPage'
|
||||||
|
@ -67,7 +67,7 @@ class Account < ApplicationRecord
|
||||||
has_many :messages, dependent: :destroy_async
|
has_many :messages, dependent: :destroy_async
|
||||||
has_many :notes, dependent: :destroy_async
|
has_many :notes, dependent: :destroy_async
|
||||||
has_many :notification_settings, dependent: :destroy_async
|
has_many :notification_settings, dependent: :destroy_async
|
||||||
has_many :notifications, dependent: :destroy
|
has_many :notifications, dependent: :destroy_async
|
||||||
has_many :portals, dependent: :destroy_async, class_name: '::Portal'
|
has_many :portals, dependent: :destroy_async, class_name: '::Portal'
|
||||||
has_many :sms_channels, dependent: :destroy_async, class_name: '::Channel::Sms'
|
has_many :sms_channels, dependent: :destroy_async, class_name: '::Channel::Sms'
|
||||||
has_many :teams, dependent: :destroy_async
|
has_many :teams, dependent: :destroy_async
|
||||||
|
|
|
@ -19,11 +19,6 @@
|
||||||
# index_account_users_on_user_id (user_id)
|
# index_account_users_on_user_id (user_id)
|
||||||
# uniq_user_id_per_account_id (account_id,user_id) UNIQUE
|
# uniq_user_id_per_account_id (account_id,user_id) UNIQUE
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (user_id => users.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
|
|
||||||
class AccountUser < ApplicationRecord
|
class AccountUser < ApplicationRecord
|
||||||
include AvailabilityStatusable
|
include AvailabilityStatusable
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
#
|
#
|
||||||
# index_agent_bots_on_account_id (account_id)
|
# index_agent_bots_on_account_id (account_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
|
|
||||||
class AgentBot < ApplicationRecord
|
class AgentBot < ApplicationRecord
|
||||||
include AccessTokenable
|
include AccessTokenable
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
# index_articles_on_associated_article_id (associated_article_id)
|
# index_articles_on_associated_article_id (associated_article_id)
|
||||||
# index_articles_on_author_id (author_id)
|
# index_articles_on_author_id (author_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (associated_article_id => articles.id)
|
|
||||||
# fk_rails_... (author_id => users.id)
|
|
||||||
#
|
|
||||||
class Article < ApplicationRecord
|
class Article < ApplicationRecord
|
||||||
include PgSearch::Model
|
include PgSearch::Model
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,6 @@
|
||||||
# index_campaigns_on_inbox_id (inbox_id)
|
# index_campaigns_on_inbox_id (inbox_id)
|
||||||
# index_campaigns_on_scheduled_at (scheduled_at)
|
# index_campaigns_on_scheduled_at (scheduled_at)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (inbox_id => inboxes.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
class Campaign < ApplicationRecord
|
class Campaign < ApplicationRecord
|
||||||
include UrlHelper
|
include UrlHelper
|
||||||
validates :account_id, presence: true
|
validates :account_id, presence: true
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
# index_categories_on_parent_category_id (parent_category_id)
|
# index_categories_on_parent_category_id (parent_category_id)
|
||||||
# index_categories_on_slug_and_locale_and_portal_id (slug,locale,portal_id) UNIQUE
|
# index_categories_on_slug_and_locale_and_portal_id (slug,locale,portal_id) UNIQUE
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (associated_category_id => categories.id)
|
|
||||||
# fk_rails_... (parent_category_id => categories.id)
|
|
||||||
#
|
|
||||||
class Category < ApplicationRecord
|
class Category < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :portal
|
belongs_to :portal
|
||||||
|
|
|
@ -19,11 +19,6 @@
|
||||||
# index_contact_inboxes_on_pubsub_token (pubsub_token) UNIQUE
|
# index_contact_inboxes_on_pubsub_token (pubsub_token) UNIQUE
|
||||||
# index_contact_inboxes_on_source_id (source_id)
|
# index_contact_inboxes_on_source_id (source_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (contact_id => contacts.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (inbox_id => inboxes.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
|
|
||||||
class ContactInbox < ApplicationRecord
|
class ContactInbox < ApplicationRecord
|
||||||
include Pubsubable
|
include Pubsubable
|
||||||
|
|
|
@ -37,12 +37,6 @@
|
||||||
# index_conversations_on_status_and_account_id (status,account_id)
|
# index_conversations_on_status_and_account_id (status,account_id)
|
||||||
# index_conversations_on_team_id (team_id)
|
# index_conversations_on_team_id (team_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (campaign_id => campaigns.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (contact_inbox_id => contact_inboxes.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (team_id => teams.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
|
|
||||||
class Conversation < ApplicationRecord
|
class Conversation < ApplicationRecord
|
||||||
include Labelable
|
include Labelable
|
||||||
|
@ -88,7 +82,7 @@ class Conversation < ApplicationRecord
|
||||||
has_many :mentions, dependent: :destroy_async
|
has_many :mentions, dependent: :destroy_async
|
||||||
has_many :messages, dependent: :destroy_async, autosave: true
|
has_many :messages, dependent: :destroy_async, autosave: true
|
||||||
has_one :csat_survey_response, dependent: :destroy_async
|
has_one :csat_survey_response, dependent: :destroy_async
|
||||||
has_many :notifications, as: :primary_actor, dependent: :destroy
|
has_many :notifications, as: :primary_actor, dependent: :destroy_async
|
||||||
|
|
||||||
before_save :ensure_snooze_until_reset
|
before_save :ensure_snooze_until_reset
|
||||||
before_create :mark_conversation_pending_if_bot
|
before_create :mark_conversation_pending_if_bot
|
||||||
|
|
|
@ -21,14 +21,6 @@
|
||||||
# index_csat_survey_responses_on_conversation_id (conversation_id)
|
# index_csat_survey_responses_on_conversation_id (conversation_id)
|
||||||
# index_csat_survey_responses_on_message_id (message_id) UNIQUE
|
# index_csat_survey_responses_on_message_id (message_id) UNIQUE
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (assigned_agent_id => users.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (contact_id => contacts.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (conversation_id => conversations.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (message_id => messages.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
class CsatSurveyResponse < ApplicationRecord
|
class CsatSurveyResponse < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :conversation
|
belongs_to :conversation
|
||||||
|
|
|
@ -15,11 +15,6 @@
|
||||||
# index_dashboard_apps_on_account_id (account_id)
|
# index_dashboard_apps_on_account_id (account_id)
|
||||||
# index_dashboard_apps_on_user_id (user_id)
|
# index_dashboard_apps_on_user_id (user_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id)
|
|
||||||
# fk_rails_... (user_id => users.id)
|
|
||||||
#
|
|
||||||
class DashboardApp < ApplicationRecord
|
class DashboardApp < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
#
|
#
|
||||||
# index_data_imports_on_account_id (account_id)
|
# index_data_imports_on_account_id (account_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
class DataImport < ApplicationRecord
|
class DataImport < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
validates :data_type, inclusion: { in: ['contacts'], message: I18n.t('errors.data_import.data_type.invalid') }
|
validates :data_type, inclusion: { in: ['contacts'], message: I18n.t('errors.data_import.data_type.invalid') }
|
||||||
|
|
|
@ -18,11 +18,6 @@
|
||||||
# index_macros_on_created_by_id (created_by_id)
|
# index_macros_on_created_by_id (created_by_id)
|
||||||
# index_macros_on_updated_by_id (updated_by_id)
|
# index_macros_on_updated_by_id (updated_by_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (created_by_id => users.id)
|
|
||||||
# fk_rails_... (updated_by_id => users.id)
|
|
||||||
#
|
|
||||||
class Macro < ApplicationRecord
|
class Macro < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :created_by,
|
belongs_to :created_by,
|
||||||
|
|
|
@ -17,11 +17,6 @@
|
||||||
# index_mentions_on_user_id (user_id)
|
# index_mentions_on_user_id (user_id)
|
||||||
# index_mentions_on_user_id_and_conversation_id (user_id,conversation_id) UNIQUE
|
# index_mentions_on_user_id_and_conversation_id (user_id,conversation_id) UNIQUE
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (conversation_id => conversations.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (user_id => users.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
class Mention < ApplicationRecord
|
class Mention < ApplicationRecord
|
||||||
include SortHandler
|
include SortHandler
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,9 @@ class Message < ApplicationRecord
|
||||||
belongs_to :contact, required: false
|
belongs_to :contact, required: false
|
||||||
belongs_to :sender, polymorphic: true, required: false
|
belongs_to :sender, polymorphic: true, required: false
|
||||||
|
|
||||||
has_many :attachments, dependent: :destroy_async, autosave: true, before_add: :validate_attachments_limit
|
has_many :attachments, dependent: :destroy, autosave: true, before_add: :validate_attachments_limit
|
||||||
has_one :csat_survey_response, dependent: :destroy_async
|
has_one :csat_survey_response, dependent: :destroy_async
|
||||||
|
has_many :notifications, as: :primary_actor, dependent: :destroy_async
|
||||||
|
|
||||||
after_create_commit :execute_after_create_commit_callbacks
|
after_create_commit :execute_after_create_commit_callbacks
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,6 @@
|
||||||
# index_notes_on_contact_id (contact_id)
|
# index_notes_on_contact_id (contact_id)
|
||||||
# index_notes_on_user_id (user_id)
|
# index_notes_on_user_id (user_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (contact_id => contacts.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (user_id => users.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
class Note < ApplicationRecord
|
class Note < ApplicationRecord
|
||||||
before_validation :ensure_account_id
|
before_validation :ensure_account_id
|
||||||
validates :content, presence: true
|
validates :content, presence: true
|
||||||
|
|
|
@ -15,10 +15,6 @@
|
||||||
# index_teams_on_account_id (account_id)
|
# index_teams_on_account_id (account_id)
|
||||||
# index_teams_on_name_and_account_id (name,account_id) UNIQUE
|
# index_teams_on_name_and_account_id (name,account_id) UNIQUE
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (account_id => accounts.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
class Team < ApplicationRecord
|
class Team < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
has_many :team_members, dependent: :destroy_async
|
has_many :team_members, dependent: :destroy_async
|
||||||
|
|
|
@ -14,11 +14,6 @@
|
||||||
# index_team_members_on_team_id_and_user_id (team_id,user_id) UNIQUE
|
# index_team_members_on_team_id_and_user_id (team_id,user_id) UNIQUE
|
||||||
# index_team_members_on_user_id (user_id)
|
# index_team_members_on_user_id (user_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
|
||||||
#
|
|
||||||
# fk_rails_... (team_id => teams.id) ON DELETE => cascade
|
|
||||||
# fk_rails_... (user_id => users.id) ON DELETE => cascade
|
|
||||||
#
|
|
||||||
class TeamMember < ApplicationRecord
|
class TeamMember < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :team
|
belongs_to :team
|
||||||
|
|
46
db/migrate/20220809104508_revert_cascading_indexes.rb
Normal file
46
db/migrate/20220809104508_revert_cascading_indexes.rb
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
class RevertCascadingIndexes < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
remove_foreign_key 'account_users', 'accounts' if foreign_key_exists? 'account_users', 'accounts'
|
||||||
|
remove_foreign_key 'account_users', 'users' if foreign_key_exists? 'account_users', 'users'
|
||||||
|
remove_foreign_key 'agent_bots', 'accounts' if foreign_key_exists? 'agent_bots', 'accounts'
|
||||||
|
remove_foreign_key 'campaigns', 'accounts' if foreign_key_exists? 'campaigns', 'accounts'
|
||||||
|
remove_foreign_key 'campaigns', 'inboxes' if foreign_key_exists? 'campaigns', 'inboxes'
|
||||||
|
remove_foreign_key 'conversations', 'campaigns' if foreign_key_exists? 'conversations', 'campaigns'
|
||||||
|
remove_foreign_key 'conversations', 'contact_inboxes' if foreign_key_exists? 'conversations', 'contact_inboxes'
|
||||||
|
remove_foreign_key 'conversations', 'teams' if foreign_key_exists? 'conversations', 'teams'
|
||||||
|
remove_foreign_key 'csat_survey_responses', 'accounts' if foreign_key_exists? 'csat_survey_responses', 'accounts'
|
||||||
|
remove_foreign_key 'csat_survey_responses', 'contacts' if foreign_key_exists? 'csat_survey_responses', 'contacts'
|
||||||
|
remove_foreign_key 'csat_survey_responses', 'conversations' if foreign_key_exists? 'csat_survey_responses', 'conversations'
|
||||||
|
remove_foreign_key 'csat_survey_responses', 'messages' if foreign_key_exists? 'csat_survey_responses', 'messages'
|
||||||
|
remove_foreign_key 'csat_survey_responses', 'users', column: 'assigned_agent_id' if foreign_key_exists? 'csat_survey_responses', 'users',
|
||||||
|
column: 'assigned_agent_id'
|
||||||
|
remove_foreign_key 'data_imports', 'accounts' if foreign_key_exists? 'data_imports', 'accounts'
|
||||||
|
remove_foreign_key 'mentions', 'conversations' if foreign_key_exists? 'mentions', 'conversations'
|
||||||
|
remove_foreign_key 'mentions', 'users' if foreign_key_exists? 'mentions', 'users'
|
||||||
|
remove_foreign_key 'notes', 'accounts' if foreign_key_exists? 'notes', 'accounts'
|
||||||
|
remove_foreign_key 'notes', 'contacts' if foreign_key_exists? 'notes', 'contacts'
|
||||||
|
remove_foreign_key 'notes', 'users' if foreign_key_exists? 'notes', 'users'
|
||||||
|
remove_foreign_key 'team_members', 'teams' if foreign_key_exists? 'team_members', 'teams'
|
||||||
|
remove_foreign_key 'team_members', 'users' if foreign_key_exists? 'team_members', 'users'
|
||||||
|
remove_foreign_key 'teams', 'accounts' if foreign_key_exists? 'teams', 'accounts'
|
||||||
|
remove_foreign_key 'contact_inboxes', 'contacts' if foreign_key_exists? 'contact_inboxes', 'contacts'
|
||||||
|
remove_foreign_key 'contact_inboxes', 'inboxes' if foreign_key_exists? 'contact_inboxes', 'inboxes'
|
||||||
|
|
||||||
|
remove_foreign_key 'articles', 'articles', column: 'associated_article_id' if foreign_key_exists? 'articles', 'articles',
|
||||||
|
column: 'associated_article_id'
|
||||||
|
remove_foreign_key 'articles', 'users', column: 'author_id' if foreign_key_exists? 'articles', 'users', column: 'author_id'
|
||||||
|
|
||||||
|
remove_foreign_key 'categories', 'categories', column: 'parent_category_id' if foreign_key_exists? 'categories', 'categories',
|
||||||
|
column: 'parent_category_id'
|
||||||
|
remove_foreign_key 'categories', 'categories', column: 'associated_category_id' if foreign_key_exists? 'categories', 'categories',
|
||||||
|
column: 'associated_category_id'
|
||||||
|
|
||||||
|
remove_foreign_key 'dashboard_apps', 'accounts' if foreign_key_exists? 'dashboard_apps', 'accounts'
|
||||||
|
remove_foreign_key 'dashboard_apps', 'users' if foreign_key_exists? 'dashboard_apps', 'users'
|
||||||
|
|
||||||
|
remove_foreign_key 'macros', 'users', column: 'created_by_id' if foreign_key_exists? 'macros', 'users', column: 'created_by_id'
|
||||||
|
remove_foreign_key 'macros', 'users', column: 'updated_by_id' if foreign_key_exists? 'macros', 'users', column: 'updated_by_id'
|
||||||
|
|
||||||
|
Migration::RemoveStaleNotificationsJob.perform_later
|
||||||
|
end
|
||||||
|
end
|
34
db/schema.rb
34
db/schema.rb
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2022_08_02_133722) do
|
ActiveRecord::Schema.define(version: 2022_08_09_104508) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
|
@ -862,40 +862,8 @@ ActiveRecord::Schema.define(version: 2022_08_02_133722) do
|
||||||
t.index ["inbox_id"], name: "index_working_hours_on_inbox_id"
|
t.index ["inbox_id"], name: "index_working_hours_on_inbox_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_foreign_key "account_users", "accounts", on_delete: :cascade
|
|
||||||
add_foreign_key "account_users", "users", on_delete: :cascade
|
|
||||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "agent_bots", "accounts", on_delete: :cascade
|
|
||||||
add_foreign_key "articles", "articles", column: "associated_article_id"
|
|
||||||
add_foreign_key "articles", "users", column: "author_id"
|
|
||||||
add_foreign_key "campaigns", "accounts", on_delete: :cascade
|
|
||||||
add_foreign_key "campaigns", "inboxes", on_delete: :cascade
|
|
||||||
add_foreign_key "categories", "categories", column: "associated_category_id"
|
|
||||||
add_foreign_key "categories", "categories", column: "parent_category_id"
|
|
||||||
add_foreign_key "contact_inboxes", "contacts", on_delete: :cascade
|
|
||||||
add_foreign_key "contact_inboxes", "inboxes", on_delete: :cascade
|
|
||||||
add_foreign_key "conversations", "campaigns", on_delete: :cascade
|
|
||||||
add_foreign_key "conversations", "contact_inboxes", on_delete: :cascade
|
|
||||||
add_foreign_key "conversations", "teams", on_delete: :cascade
|
|
||||||
add_foreign_key "csat_survey_responses", "accounts", on_delete: :cascade
|
|
||||||
add_foreign_key "csat_survey_responses", "contacts", on_delete: :cascade
|
|
||||||
add_foreign_key "csat_survey_responses", "conversations", on_delete: :cascade
|
|
||||||
add_foreign_key "csat_survey_responses", "messages", on_delete: :cascade
|
|
||||||
add_foreign_key "csat_survey_responses", "users", column: "assigned_agent_id", on_delete: :cascade
|
|
||||||
add_foreign_key "dashboard_apps", "accounts"
|
|
||||||
add_foreign_key "dashboard_apps", "users"
|
|
||||||
add_foreign_key "data_imports", "accounts", on_delete: :cascade
|
|
||||||
add_foreign_key "macros", "users", column: "created_by_id"
|
|
||||||
add_foreign_key "macros", "users", column: "updated_by_id"
|
|
||||||
add_foreign_key "mentions", "conversations", on_delete: :cascade
|
|
||||||
add_foreign_key "mentions", "users", on_delete: :cascade
|
|
||||||
add_foreign_key "notes", "accounts", on_delete: :cascade
|
|
||||||
add_foreign_key "notes", "contacts", on_delete: :cascade
|
|
||||||
add_foreign_key "notes", "users", on_delete: :cascade
|
|
||||||
add_foreign_key "team_members", "teams", on_delete: :cascade
|
|
||||||
add_foreign_key "team_members", "users", on_delete: :cascade
|
|
||||||
add_foreign_key "teams", "accounts", on_delete: :cascade
|
|
||||||
create_trigger("accounts_after_insert_row_tr", :generated => true, :compatibility => 1).
|
create_trigger("accounts_after_insert_row_tr", :generated => true, :compatibility => 1).
|
||||||
on("accounts").
|
on("accounts").
|
||||||
after(:insert).
|
after(:insert).
|
||||||
|
|
|
@ -581,12 +581,17 @@ RSpec.describe Conversation, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#delete conversation' do
|
describe '#delete conversation' do
|
||||||
|
include ActiveJob::TestHelper
|
||||||
|
|
||||||
let!(:conversation) { create(:conversation) }
|
let!(:conversation) { create(:conversation) }
|
||||||
|
|
||||||
let!(:notification) { create(:notification, notification_type: 'conversation_creation', primary_actor: conversation) }
|
let!(:notification) { create(:notification, notification_type: 'conversation_creation', primary_actor: conversation) }
|
||||||
|
|
||||||
it 'delete associated notifications if conversation is deleted' do
|
it 'delete associated notifications if conversation is deleted' do
|
||||||
conversation.destroy!
|
perform_enqueued_jobs do
|
||||||
|
conversation.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
expect { notification.reload }.to raise_error ActiveRecord::RecordNotFound
|
expect { notification.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe Notification do
|
RSpec.describe Notification do
|
||||||
|
include ActiveJob::TestHelper
|
||||||
|
|
||||||
context 'with associations' do
|
context 'with associations' do
|
||||||
it { is_expected.to belong_to(:account) }
|
it { is_expected.to belong_to(:account) }
|
||||||
it { is_expected.to belong_to(:user) }
|
it { is_expected.to belong_to(:user) }
|
||||||
|
@ -97,4 +99,17 @@ RSpec.describe Notification do
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when primary actory is deleted' do
|
||||||
|
let!(:conversation) { create(:conversation) }
|
||||||
|
|
||||||
|
it 'clears notifications' do
|
||||||
|
notification = create(:notification, notification_type: 'conversation_creation', primary_actor: conversation)
|
||||||
|
perform_enqueued_jobs do
|
||||||
|
conversation.inbox.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
expect { notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue