discourse/db/migrate/20241025045928_add_invites_link_to_sidebar.rb
Osama Sayegh 397d41008e
Some checks are pending
Licenses / run (push) Waiting to run
Linting / run (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (annotations, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, themes) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, chat) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, themes) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Chrome) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox ESR) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox Evergreen) (push) Waiting to run
FIX: Account for sidebars with no primary links when adding invite link (#29535)
Meta topic: https://meta.discourse.org/t/stumped-about-launcher-rebuild-app-error-process-pid-2096/333876?u=osama.

Follow up to 19672faba6.

The migration that adds the invite link to the sidebar determines the position of the link by looking up the max position that a primary link has and inserts the invite link at the max position plus 1. This approach works fine for most sites, however, sites that have deleted all primary links from the sidebar will fail because the max position will be `nil` which blows up the migration.

This commit addresses this edge case by falling back to looking up the min position of secondary links,    or to zero if there're also no secondary links, and then inserts the invite link at the min position minus 1.
2024-11-01 10:31:21 +03:00

65 lines
2.3 KiB
Ruby

# frozen_string_literal: true
class AddInvitesLinkToSidebar < ActiveRecord::Migration[7.1]
def up
community_section_id = DB.query_single(<<~SQL).first
SELECT id
FROM sidebar_sections
WHERE section_type = 0
SQL
return if !community_section_id
max_position = DB.query_single(<<~SQL, section_id: community_section_id).first
SELECT MAX(ssl.position)
FROM sidebar_urls su
JOIN sidebar_section_links ssl ON su.id = ssl.linkable_id
WHERE ssl.linkable_type = 'SidebarUrl'
AND ssl.sidebar_section_id = :section_id
AND su.segment = 0
SQL
max_position ||= (DB.query_single(<<~SQL, section_id: community_section_id).first || 0) - 1
SELECT MIN(ssl.position)
FROM sidebar_urls su
JOIN sidebar_section_links ssl ON su.id = ssl.linkable_id
WHERE ssl.linkable_type = 'SidebarUrl'
AND ssl.sidebar_section_id = :section_id
AND su.segment = 1
SQL
updated_rows = DB.query_hash(<<~SQL, position: max_position, section_id: community_section_id)
DELETE FROM sidebar_section_links
WHERE position > :position
AND sidebar_section_id = :section_id
AND linkable_type = 'SidebarUrl'
RETURNING user_id, linkable_id, linkable_type, sidebar_section_id, position + 1 AS position, created_at, updated_at
SQL
updated_rows.each { |row| DB.exec(<<~SQL, **row.symbolize_keys) }
INSERT INTO sidebar_section_links
(user_id, linkable_id, linkable_type, sidebar_section_id, position, created_at, updated_at)
VALUES
(:user_id, :linkable_id, :linkable_type, :sidebar_section_id, :position, :created_at, :updated_at)
SQL
link_id = DB.query_single(<<~SQL).first
INSERT INTO sidebar_urls
(name, value, icon, external, segment, created_at, updated_at)
VALUES
('Invite', '/new-invite', 'paper-plane', false, 0, now(), now())
RETURNING sidebar_urls.id
SQL
DB.exec(<<~SQL, link_id:, section_id: community_section_id, position: max_position + 1)
INSERT INTO sidebar_section_links
(user_id, linkable_id, linkable_type, sidebar_section_id, position, created_at, updated_at)
VALUES
(-1, :link_id, 'SidebarUrl', :section_id, :position, now(), now())
SQL
end
def down
raise ActiveRecord::IrreversibleMigration
end
end