0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 02:19:55 +08:00
discourse/db/migrate/20241025045928_add_invites_link_to_sidebar.rb
David Taylor 85693658ff
DEV: Move Community sidebar section + links from migrations to seed fixture (#39973)
Previously, the Community sidebar section, its 12 default URLs, and the
links binding them were inserted across four migrations
(`20230411032053_insert_community_to_sidebar_sections.rb`,
`20241025045928_add_invites_link_to_sidebar.rb`,
`20250626090725_add_my_messages_link_to_sidebar.rb`,
`20250721043317_add_filter_link_to_sidebar.rb`), mixing schema and data
and re-running data inserts every time a new link was added.

This change moves the rows to `db/fixtures/700_sidebar.rb`, gated by a
hidden `sidebar_seeded` site setting so admin customizations (renamed
links, reordering, even destroying the public Community section via
`sidebar_sections_controller#destroy`) survive subsequent `db:seed`
runs. The fixture iterates `SidebarUrl::COMMUNITY_SECTION_LINKS` so
adding a future link is a one-line model change plus a re-seed.

The four existing migrations are gated on `Migration::Helpers.new_site?`
so they continue to upgrade existing sites past the point the link
didn't yet exist, but no-op on fresh installs (where the fixture is the
source of truth). A companion
`20260513105516_mark_existing_sites_sidebar_seeded.rb` flips the flag
for existing sites so the seed bails immediately on the upgrade deploy.

Extracted from https://github.com/discourse/discourse/pull/39788.
2026-05-13 12:13:12 +01:00

66 lines
2.4 KiB
Ruby
Vendored

# frozen_string_literal: true
class AddInvitesLinkToSidebar < ActiveRecord::Migration[7.1]
def up
return if Migration::Helpers.new_site?
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