mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 14:03:22 +08:00
FIX: Prevent field type migration from poisoning AR cache (#27549)
We previously migrated field_type from a string to an integer backed enum. Part of this involved renaming a column in a post migration, swapping out field_type:string for field_type:integer. This borks the ActiveRecord cache since the application is already running. Rebooting fixes it, but we want to avoid having this happen in the first place.
This commit is contained in:
parent
dd329d55a5
commit
920aa2dfce
|
@ -6,6 +6,7 @@ class UserField < ActiveRecord::Base
|
|||
include HasSanitizableFields
|
||||
|
||||
deprecate_column :required, drop_from: "3.3"
|
||||
self.ignored_columns += %i[field_type]
|
||||
|
||||
validates_presence_of :description
|
||||
validates_presence_of :name, unless: -> { field_type == "confirm" }
|
||||
|
@ -19,7 +20,8 @@ class UserField < ActiveRecord::Base
|
|||
scope :public_fields, -> { where(show_on_profile: true).or(where(show_on_user_card: true)) }
|
||||
|
||||
enum :requirement, { optional: 0, for_all_users: 1, on_signup: 2 }.freeze
|
||||
enum :field_type, { text: 0, confirm: 1, dropdown: 2, multiselect: 3 }.freeze
|
||||
enum :field_type_enum, { text: 0, confirm: 1, dropdown: 2, multiselect: 3 }.freeze
|
||||
alias_attribute :field_type, :field_type_enum
|
||||
|
||||
def self.max_length
|
||||
2048
|
||||
|
@ -60,5 +62,5 @@ end
|
|||
# external_type :string
|
||||
# searchable :boolean default(FALSE), not null
|
||||
# requirement :integer default("optional"), not null
|
||||
# field_type :integer not null
|
||||
# field_type_enum :integer not null
|
||||
#
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddBackFieldTypeEnumToUserFields < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
# NOTE: This is here to undo the swap done in SwapFieldTypeWithFieldTypeEnumOnUserFields,
|
||||
# as that change was breaking the AR cache until the application is rebooted.
|
||||
# The condition here is to ensure it's only executed if that post-migration has been
|
||||
# applied.
|
||||
if !ActiveRecord::Base.connection.column_exists?(:user_fields, :field_type_enum)
|
||||
add_column :user_fields, :field_type_enum, :integer
|
||||
change_column_null :user_fields, :field_type, true
|
||||
|
||||
execute(<<~SQL)
|
||||
UPDATE user_fields
|
||||
SET field_type_enum = field_type
|
||||
SQL
|
||||
|
||||
change_column_null :user_fields, :field_type_enum, false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,14 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SwapFieldTypeWithFieldTypeEnumOnUserFields < ActiveRecord::Migration[7.0]
|
||||
DROPPED_COLUMNS ||= { user_fields: %i[field_type] }
|
||||
# DROPPED_COLUMNS ||= { user_fields: %i[field_type] }
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each { |table, columns| Migration::ColumnDropper.execute_drop(table, columns) }
|
||||
rename_column :user_fields, :field_type_enum, :field_type
|
||||
end
|
||||
# def up
|
||||
# # WARNING: Swapping in a column of a different type in a post-migration will break the AR
|
||||
# # cache, since the application is already booted, requiring a restart.
|
||||
# #
|
||||
# DROPPED_COLUMNS.each { |table, columns| Migration::ColumnDropper.execute_drop(table, columns) }
|
||||
# rename_column :user_fields, :field_type_enum, :field_type
|
||||
# end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
# def down
|
||||
# raise ActiveRecord::IrreversibleMigration
|
||||
# end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user