DEV: Custom generator for rename site setting migration (#24841)

Ability to automatically generate migration when site setting name is changed.
Example usage: `rails generate site_setting_rename_migration site_description contact_email`
This commit is contained in:
Krzysztof Kotlarek 2023-12-13 09:58:45 +11:00 committed by GitHub
parent 6755fd3b62
commit 5055e431a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 0 deletions

View File

@ -0,0 +1,8 @@
Description:
Generates migration to rename a site setting name from an old name to a new site setting name. This assumes that the new setting is the same data format as the old one.
Example:
bin/rails generate site_setting_rename_migration old_setting_name new_setting_name
This will create:
db/migrate/20231212111111_rename_old_setting_name_setting.rb

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
class SiteSettingRenameMigrationGenerator < Rails::Generators::Base
argument :old_name, type: :string, banner: "old setting name", required: true
argument :new_name, type: :string, banner: "new setting name", required: true
def create_migration_file
timestamp = Time.zone.now.to_s.tr("^0-9", "")[0..13]
file_path = "db/migrate/#{timestamp}_rename_#{old_name}_setting.rb"
class_name = "Rename#{old_name.classify}Setting"
validate_setting_name!(old_name)
validate_setting_name!(new_name)
create_file file_path, <<~MIGRATION_FILE
# frozen_string_literal: true
class #{class_name} < ActiveRecord::Migration[7.0]
def up
execute "UPDATE site_settings SET name = '#{new_name}' WHERE name = '#{old_name}'"
end
def down
execute "UPDATE site_settings SET name = '#{old_name}' WHERE name = '#{new_name}'"
end
end
MIGRATION_FILE
end
private
def validate_setting_name!(name)
begin
SiteSetting.send(name)
rescue NoMethodError
say "Site setting with #{name} does not exist"
raise ArgumentError
end
end
end

View File

@ -0,0 +1,38 @@
# frozen_string_literal: true
require "rails_helper"
require "rails/generators"
require "generators/site_setting_rename_migration/site_setting_rename_migration_generator"
RSpec.describe SiteSettingRenameMigrationGenerator, type: :generator do
it "generates the correct migration" do
freeze_time DateTime.parse("2010-01-01 12:00")
described_class.start(%w[site_description contact_email], destination_root: "#{Rails.root}/tmp")
file_path = "#{Rails.root}/tmp/db/migrate/20100101120000_rename_site_description_setting.rb"
expected_content = <<~EXPECTED_CONTENT
# frozen_string_literal: true
class RenameSiteDescriptionSetting < ActiveRecord::Migration[7.0]
def up
execute "UPDATE site_settings SET name = 'contact_email' WHERE name = 'site_description'"
end
def down
execute "UPDATE site_settings SET name = 'site_description' WHERE name = 'contact_email'"
end
end
EXPECTED_CONTENT
expect(File.read(file_path)).to eq(expected_content)
File.delete(file_path)
end
it "raises an error when old name is incorrect" do
expect { described_class.start(%w[wrong_name contact_email]) }.to raise_error(ArgumentError)
end
it "raises an error when new name is incorrect" do
expect { described_class.start(%w[site_description wrong_name]) }.to raise_error(ArgumentError)
end
end