Class: SidebarSiteSettingsBackfiller
- Inherits:
-
Object
- Object
- SidebarSiteSettingsBackfiller
- Defined in:
- app/services/sidebar_site_settings_backfiller.rb
Overview
A service class that backfills the changes to the default sidebar categories and tags site settings.
When a category/tag is removed from the site settings, the ‘SidebarSectionLink` records associated with the category/tag are deleted.
When a category/tag is added to the site settings, a ‘SidebarSectionLink` record for the associated category/tag are created for all users that do not already have a `SidebarSectionLink` record for the category/tag.
Instance Method Summary collapse
-
#backfill! ⇒ Object
This should only be called from the ‘Jobs::BackfillSidebarSiteSettings` job as the job is ran with a cluster concurrency of 1 to ensure that only one process is running the backfill at any point in time.
-
#initialize(setting_name, previous_value:, new_value:) ⇒ SidebarSiteSettingsBackfiller
constructor
A new instance of SidebarSiteSettingsBackfiller.
- #number_of_users_to_backfill ⇒ Object
Constructor Details
#initialize(setting_name, previous_value:, new_value:) ⇒ SidebarSiteSettingsBackfiller
Returns a new instance of SidebarSiteSettingsBackfiller.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'app/services/sidebar_site_settings_backfiller.rb', line 11 def initialize(setting_name, previous_value:, new_value:) @setting_name = setting_name @linkable_klass, previous_ids, new_ids = case setting_name when "default_navigation_menu_categories" [Category, previous_value.split("|").map(&:to_i), new_value.split("|").map(&:to_i)] when "default_navigation_menu_tags" klass = Tag [ klass, klass.where(name: previous_value.split("|")).pluck(:id), klass.where(name: new_value.split("|")).pluck(:id), ] else raise "Invalid setting_name" end @added_ids = new_ids - previous_ids @removed_ids = previous_ids - new_ids end |
Instance Method Details
#backfill! ⇒ Object
This should only be called from the ‘Jobs::BackfillSidebarSiteSettings` job as the job is ran with a cluster concurrency of 1 to ensure that only one process is running the backfill at any point in time.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'app/services/sidebar_site_settings_backfiller.rb', line 36 def backfill! User .real .where(staged: false) .select(:id) .find_in_batches do |users| rows = [] user_ids = users.map(&:id) user_ids.each do |user_id| @added_ids.each do |linkable_id| rows << { user_id: user_id, linkable_type: @linkable_klass.to_s, linkable_id: linkable_id, } end end SidebarSectionLink.transaction do SidebarSectionLink.where( user_id: user_ids, linkable_id: @removed_ids, linkable_type: @linkable_klass.to_s, ).delete_all SidebarSectionLink.insert_all(rows) if rows.present? end end end |
#number_of_users_to_backfill ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'app/services/sidebar_site_settings_backfiller.rb', line 67 def number_of_users_to_backfill select_statements = [] select_statements.push(<<~SQL) if @removed_ids.present? SELECT sidebar_section_links.user_id FROM sidebar_section_links WHERE sidebar_section_links.linkable_type = '#{@linkable_klass}' AND sidebar_section_links.linkable_id IN (#{@removed_ids.join(",")}) SQL if @added_ids.present? # Returns the ids of users that will receive the new additions by excluding the users that already have the additions # Note that we want to avoid doing a left outer join against the "sidebar_section_links" table as PG will end up having # to do a full table join for both tables first which is less efficient and can be slow on large sites. select_statements.push(<<~SQL) SELECT users.id FROM users WHERE users.id NOT IN ( SELECT DISTINCT(sidebar_section_links.user_id) FROM sidebar_section_links WHERE sidebar_section_links.linkable_type = '#{@linkable_klass}' AND sidebar_section_links.linkable_id IN (#{@added_ids.join(",")}) ) AND users.id > 0 AND NOT users.staged SQL end return 0 if select_statements.blank? DB.query_single(<<~SQL)[0] SELECT COUNT(*) FROM (#{select_statements.join("\nUNION DISTINCT\n")}) AS user_ids SQL end |