fix ax modifier column naming and migration approach
This commit is contained in:
parent
65f30cb05d
commit
5fd2f5758d
5 changed files with 152 additions and 86 deletions
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
||||
# Old AX_MAPPING from WeaponProcessor: game_skill_id (string) => internal_value (integer)
|
||||
# We need the reverse: internal_value => game_skill_id
|
||||
# Old AX_MAPPING from WeaponProcessor stored internal integer values (0, 1, 2...)
|
||||
# We need to map: old internal_value => game_skill_id => weapon_stat_modifier.id
|
||||
OLD_INTERNAL_TO_GAME_SKILL_ID = {
|
||||
2 => 1588, # HP
|
||||
0 => 1589, # ATK
|
||||
|
|
@ -24,73 +24,92 @@ class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
|||
}.freeze
|
||||
|
||||
def up
|
||||
# Build lookup cache: game_skill_id -> weapon_stat_modifier.id
|
||||
# Build lookup: old_internal_value -> new FK id
|
||||
modifier_by_game_skill_id = WeaponStatModifier.pluck(:game_skill_id, :id).to_h
|
||||
|
||||
# Migrate CollectionWeapon ax_modifier1
|
||||
CollectionWeapon.where.not(ax_modifier1: nil).find_each do |cw|
|
||||
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[cw.ax_modifier1]
|
||||
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||
if modifier_id
|
||||
cw.update_columns(ax_modifier1_ref_id: modifier_id)
|
||||
else
|
||||
Rails.logger.warn "[MigrateAxModifiers] Unknown ax_modifier1=#{cw.ax_modifier1} on CollectionWeapon##{cw.id}"
|
||||
end
|
||||
old_to_new_id = OLD_INTERNAL_TO_GAME_SKILL_ID.transform_values do |game_skill_id|
|
||||
modifier_by_game_skill_id[game_skill_id]
|
||||
end
|
||||
|
||||
# Migrate CollectionWeapon ax_modifier2
|
||||
CollectionWeapon.where.not(ax_modifier2: nil).find_each do |cw|
|
||||
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[cw.ax_modifier2]
|
||||
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||
if modifier_id
|
||||
cw.update_columns(ax_modifier2_ref_id: modifier_id)
|
||||
else
|
||||
Rails.logger.warn "[MigrateAxModifiers] Unknown ax_modifier2=#{cw.ax_modifier2} on CollectionWeapon##{cw.id}"
|
||||
end
|
||||
end
|
||||
# Use raw SQL to query old integer columns (ax_modifier1, ax_modifier2)
|
||||
# and update the new FK columns (ax_modifier1_id, ax_modifier2_id)
|
||||
|
||||
# Migrate GridWeapon ax_modifier1
|
||||
GridWeapon.where.not(ax_modifier1: nil).find_each do |gw|
|
||||
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[gw.ax_modifier1]
|
||||
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||
if modifier_id
|
||||
gw.update_columns(ax_modifier1_ref_id: modifier_id)
|
||||
else
|
||||
Rails.logger.warn "[MigrateAxModifiers] Unknown ax_modifier1=#{gw.ax_modifier1} on GridWeapon##{gw.id}"
|
||||
end
|
||||
end
|
||||
# Migrate CollectionWeapon
|
||||
execute <<-SQL.squish
|
||||
UPDATE collection_weapons
|
||||
SET ax_modifier1_id = CASE ax_modifier1
|
||||
#{old_to_new_id.map { |old_val, new_id| "WHEN #{old_val} THEN #{new_id}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier1 IS NOT NULL
|
||||
SQL
|
||||
|
||||
# Migrate GridWeapon ax_modifier2
|
||||
GridWeapon.where.not(ax_modifier2: nil).find_each do |gw|
|
||||
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[gw.ax_modifier2]
|
||||
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||
if modifier_id
|
||||
gw.update_columns(ax_modifier2_ref_id: modifier_id)
|
||||
else
|
||||
Rails.logger.warn "[MigrateAxModifiers] Unknown ax_modifier2=#{gw.ax_modifier2} on GridWeapon##{gw.id}"
|
||||
end
|
||||
end
|
||||
execute <<-SQL.squish
|
||||
UPDATE collection_weapons
|
||||
SET ax_modifier2_id = CASE ax_modifier2
|
||||
#{old_to_new_id.map { |old_val, new_id| "WHEN #{old_val} THEN #{new_id}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier2 IS NOT NULL
|
||||
SQL
|
||||
|
||||
# Migrate GridWeapon
|
||||
execute <<-SQL.squish
|
||||
UPDATE grid_weapons
|
||||
SET ax_modifier1_id = CASE ax_modifier1
|
||||
#{old_to_new_id.map { |old_val, new_id| "WHEN #{old_val} THEN #{new_id}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier1 IS NOT NULL
|
||||
SQL
|
||||
|
||||
execute <<-SQL.squish
|
||||
UPDATE grid_weapons
|
||||
SET ax_modifier2_id = CASE ax_modifier2
|
||||
#{old_to_new_id.map { |old_val, new_id| "WHEN #{old_val} THEN #{new_id}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier2 IS NOT NULL
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
# Build reverse lookup: game_skill_id -> old internal value
|
||||
# Build reverse lookup: new FK id -> old internal value
|
||||
modifier_by_game_skill_id = WeaponStatModifier.pluck(:game_skill_id, :id).to_h
|
||||
game_skill_id_to_internal = OLD_INTERNAL_TO_GAME_SKILL_ID.invert
|
||||
|
||||
# Reverse: copy FK back to integer columns using old internal values
|
||||
WeaponStatModifier.find_each do |modifier|
|
||||
next unless modifier.game_skill_id
|
||||
|
||||
internal_value = game_skill_id_to_internal[modifier.game_skill_id]
|
||||
next unless internal_value
|
||||
|
||||
CollectionWeapon.where(ax_modifier1_ref_id: modifier.id)
|
||||
.update_all(ax_modifier1: internal_value)
|
||||
CollectionWeapon.where(ax_modifier2_ref_id: modifier.id)
|
||||
.update_all(ax_modifier2: internal_value)
|
||||
GridWeapon.where(ax_modifier1_ref_id: modifier.id)
|
||||
.update_all(ax_modifier1: internal_value)
|
||||
GridWeapon.where(ax_modifier2_ref_id: modifier.id)
|
||||
.update_all(ax_modifier2: internal_value)
|
||||
new_id_to_old = modifier_by_game_skill_id.each_with_object({}) do |(game_skill_id, new_id), hash|
|
||||
old_val = game_skill_id_to_internal[game_skill_id]
|
||||
hash[new_id] = old_val if old_val
|
||||
end
|
||||
|
||||
return if new_id_to_old.empty?
|
||||
|
||||
# Reverse: copy FK back to old integer columns
|
||||
execute <<-SQL.squish
|
||||
UPDATE collection_weapons
|
||||
SET ax_modifier1 = CASE ax_modifier1_id
|
||||
#{new_id_to_old.map { |new_id, old_val| "WHEN #{new_id} THEN #{old_val}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier1_id IS NOT NULL
|
||||
SQL
|
||||
|
||||
execute <<-SQL.squish
|
||||
UPDATE collection_weapons
|
||||
SET ax_modifier2 = CASE ax_modifier2_id
|
||||
#{new_id_to_old.map { |new_id, old_val| "WHEN #{new_id} THEN #{old_val}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier2_id IS NOT NULL
|
||||
SQL
|
||||
|
||||
execute <<-SQL.squish
|
||||
UPDATE grid_weapons
|
||||
SET ax_modifier1 = CASE ax_modifier1_id
|
||||
#{new_id_to_old.map { |new_id, old_val| "WHEN #{new_id} THEN #{old_val}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier1_id IS NOT NULL
|
||||
SQL
|
||||
|
||||
execute <<-SQL.squish
|
||||
UPDATE grid_weapons
|
||||
SET ax_modifier2 = CASE ax_modifier2_id
|
||||
#{new_id_to_old.map { |new_id, old_val| "WHEN #{new_id} THEN #{old_val}" }.join(' ')}
|
||||
END
|
||||
WHERE ax_modifier2_id IS NOT NULL
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
DataMigrate::Data.define(version: 20251214193836)
|
||||
DataMigrate::Data.define(version: 20251230000002)
|
||||
|
|
|
|||
|
|
@ -3,23 +3,34 @@
|
|||
class AddWeaponStatModifierFks < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
# collection_weapons - add FK columns
|
||||
add_reference :collection_weapons, :ax_modifier1_ref,
|
||||
foreign_key: { to_table: :weapon_stat_modifiers }
|
||||
add_reference :collection_weapons, :ax_modifier2_ref,
|
||||
foreign_key: { to_table: :weapon_stat_modifiers }
|
||||
add_reference :collection_weapons, :befoulment_modifier,
|
||||
foreign_key: { to_table: :weapon_stat_modifiers }
|
||||
# Note: old ax_modifier1/ax_modifier2 integer columns still exist for data migration
|
||||
add_column :collection_weapons, :ax_modifier1_id, :bigint
|
||||
add_column :collection_weapons, :ax_modifier2_id, :bigint
|
||||
add_column :collection_weapons, :befoulment_modifier_id, :bigint
|
||||
add_column :collection_weapons, :befoulment_strength, :float
|
||||
add_column :collection_weapons, :exorcism_level, :integer, default: 0
|
||||
|
||||
add_index :collection_weapons, :ax_modifier1_id
|
||||
add_index :collection_weapons, :ax_modifier2_id
|
||||
add_index :collection_weapons, :befoulment_modifier_id
|
||||
|
||||
add_foreign_key :collection_weapons, :weapon_stat_modifiers, column: :ax_modifier1_id
|
||||
add_foreign_key :collection_weapons, :weapon_stat_modifiers, column: :ax_modifier2_id
|
||||
add_foreign_key :collection_weapons, :weapon_stat_modifiers, column: :befoulment_modifier_id
|
||||
|
||||
# grid_weapons - same pattern
|
||||
add_reference :grid_weapons, :ax_modifier1_ref,
|
||||
foreign_key: { to_table: :weapon_stat_modifiers }
|
||||
add_reference :grid_weapons, :ax_modifier2_ref,
|
||||
foreign_key: { to_table: :weapon_stat_modifiers }
|
||||
add_reference :grid_weapons, :befoulment_modifier,
|
||||
foreign_key: { to_table: :weapon_stat_modifiers }
|
||||
add_column :grid_weapons, :ax_modifier1_id, :bigint
|
||||
add_column :grid_weapons, :ax_modifier2_id, :bigint
|
||||
add_column :grid_weapons, :befoulment_modifier_id, :bigint
|
||||
add_column :grid_weapons, :befoulment_strength, :float
|
||||
add_column :grid_weapons, :exorcism_level, :integer, default: 0
|
||||
|
||||
add_index :grid_weapons, :ax_modifier1_id
|
||||
add_index :grid_weapons, :ax_modifier2_id
|
||||
add_index :grid_weapons, :befoulment_modifier_id
|
||||
|
||||
add_foreign_key :grid_weapons, :weapon_stat_modifiers, column: :ax_modifier1_id
|
||||
add_foreign_key :grid_weapons, :weapon_stat_modifiers, column: :ax_modifier2_id
|
||||
add_foreign_key :grid_weapons, :weapon_stat_modifiers, column: :befoulment_modifier_id
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,16 +2,10 @@
|
|||
|
||||
class FinalizeAxModifierColumns < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
# Remove old integer columns
|
||||
# Remove old integer columns (data has been migrated to ax_modifier1_id/ax_modifier2_id FKs)
|
||||
remove_column :collection_weapons, :ax_modifier1, :integer
|
||||
remove_column :collection_weapons, :ax_modifier2, :integer
|
||||
remove_column :grid_weapons, :ax_modifier1, :integer
|
||||
remove_column :grid_weapons, :ax_modifier2, :integer
|
||||
|
||||
# Rename new FK columns to the original names
|
||||
rename_column :collection_weapons, :ax_modifier1_ref_id, :ax_modifier1_id
|
||||
rename_column :collection_weapons, :ax_modifier2_ref_id, :ax_modifier2_id
|
||||
rename_column :grid_weapons, :ax_modifier1_ref_id, :ax_modifier1_id
|
||||
rename_column :grid_weapons, :ax_modifier2_ref_id, :ax_modifier2_id
|
||||
end
|
||||
end
|
||||
|
|
|
|||
54
db/schema.rb
54
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_12_30_000004) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "btree_gin"
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
|
|
@ -235,15 +235,21 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
t.uuid "weapon_key4_id"
|
||||
t.uuid "awakening_id"
|
||||
t.integer "awakening_level", default: 1, null: false
|
||||
t.integer "ax_modifier1"
|
||||
t.float "ax_strength1"
|
||||
t.integer "ax_modifier2"
|
||||
t.float "ax_strength2"
|
||||
t.integer "element"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "game_id"
|
||||
t.bigint "ax_modifier1_id"
|
||||
t.bigint "ax_modifier2_id"
|
||||
t.bigint "befoulment_modifier_id"
|
||||
t.float "befoulment_strength"
|
||||
t.integer "exorcism_level", default: 0
|
||||
t.index ["awakening_id"], name: "index_collection_weapons_on_awakening_id"
|
||||
t.index ["ax_modifier1_id"], name: "index_collection_weapons_on_ax_modifier1_id"
|
||||
t.index ["ax_modifier2_id"], name: "index_collection_weapons_on_ax_modifier2_id"
|
||||
t.index ["befoulment_modifier_id"], name: "index_collection_weapons_on_befoulment_modifier_id"
|
||||
t.index ["user_id", "game_id"], name: "index_collection_weapons_on_user_id_and_game_id", unique: true, where: "(game_id IS NOT NULL)"
|
||||
t.index ["user_id", "weapon_id"], name: "index_collection_weapons_on_user_id_and_weapon_id"
|
||||
t.index ["user_id"], name: "index_collection_weapons_on_user_id"
|
||||
|
|
@ -381,9 +387,11 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
t.datetime "updated_at", null: false
|
||||
t.integer "reroll_slot"
|
||||
t.uuid "collection_artifact_id"
|
||||
t.boolean "orphaned", default: false, null: false
|
||||
t.index ["artifact_id"], name: "index_grid_artifacts_on_artifact_id"
|
||||
t.index ["collection_artifact_id"], name: "index_grid_artifacts_on_collection_artifact_id"
|
||||
t.index ["grid_character_id"], name: "index_grid_artifacts_on_grid_character_id", unique: true
|
||||
t.index ["orphaned"], name: "index_grid_artifacts_on_orphaned"
|
||||
end
|
||||
|
||||
create_table "grid_characters", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||
|
|
@ -422,7 +430,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
t.integer "transcendence_step", default: 0, null: false
|
||||
t.boolean "quick_summon", default: false
|
||||
t.uuid "collection_summon_id"
|
||||
t.boolean "orphaned", default: false, null: false
|
||||
t.index ["collection_summon_id"], name: "index_grid_summons_on_collection_summon_id"
|
||||
t.index ["orphaned"], name: "index_grid_summons_on_orphaned"
|
||||
t.index ["party_id", "position"], name: "index_grid_summons_on_party_id_and_position"
|
||||
t.index ["party_id"], name: "index_grid_summons_on_party_id"
|
||||
t.index ["summon_id"], name: "index_grid_summons_on_summon_id"
|
||||
|
|
@ -439,9 +449,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.uuid "weapon_key3_id"
|
||||
t.integer "ax_modifier1"
|
||||
t.float "ax_strength1"
|
||||
t.integer "ax_modifier2"
|
||||
t.float "ax_strength2"
|
||||
t.integer "element"
|
||||
t.integer "awakening_level", default: 1, null: false
|
||||
|
|
@ -449,8 +457,18 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
t.integer "transcendence_step", default: 0
|
||||
t.string "weapon_key4_id"
|
||||
t.uuid "collection_weapon_id"
|
||||
t.boolean "orphaned", default: false, null: false
|
||||
t.bigint "ax_modifier1_id"
|
||||
t.bigint "ax_modifier2_id"
|
||||
t.bigint "befoulment_modifier_id"
|
||||
t.float "befoulment_strength"
|
||||
t.integer "exorcism_level", default: 0
|
||||
t.index ["awakening_id"], name: "index_grid_weapons_on_awakening_id"
|
||||
t.index ["ax_modifier1_id"], name: "index_grid_weapons_on_ax_modifier1_id"
|
||||
t.index ["ax_modifier2_id"], name: "index_grid_weapons_on_ax_modifier2_id"
|
||||
t.index ["befoulment_modifier_id"], name: "index_grid_weapons_on_befoulment_modifier_id"
|
||||
t.index ["collection_weapon_id"], name: "index_grid_weapons_on_collection_weapon_id"
|
||||
t.index ["orphaned"], name: "index_grid_weapons_on_orphaned"
|
||||
t.index ["party_id", "position"], name: "index_grid_weapons_on_party_id_and_position"
|
||||
t.index ["party_id"], name: "index_grid_weapons_on_party_id"
|
||||
t.index ["weapon_id"], name: "index_grid_weapons_on_weapon_id"
|
||||
|
|
@ -924,7 +942,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
t.boolean "element_changeable", default: false, null: false
|
||||
t.boolean "has_weapon_keys", default: false, null: false
|
||||
t.boolean "has_awakening", default: false, null: false
|
||||
t.boolean "has_ax_skills", default: false, null: false
|
||||
t.integer "augment_type", default: 0, null: false
|
||||
t.index ["order"], name: "index_weapon_series_on_order"
|
||||
t.index ["slug"], name: "index_weapon_series_on_slug", unique: true
|
||||
end
|
||||
|
|
@ -945,6 +963,24 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
t.index ["weapon_granblue_id"], name: "index_weapon_skills_on_weapon_granblue_id"
|
||||
end
|
||||
|
||||
create_table "weapon_stat_modifiers", force: :cascade do |t|
|
||||
t.string "slug", null: false
|
||||
t.string "name_en", null: false
|
||||
t.string "name_jp"
|
||||
t.string "category", null: false
|
||||
t.string "stat"
|
||||
t.integer "polarity", default: 1, null: false
|
||||
t.string "suffix"
|
||||
t.float "base_min"
|
||||
t.float "base_max"
|
||||
t.integer "game_skill_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["category"], name: "index_weapon_stat_modifiers_on_category"
|
||||
t.index ["game_skill_id"], name: "index_weapon_stat_modifiers_on_game_skill_id", unique: true
|
||||
t.index ["slug"], name: "index_weapon_stat_modifiers_on_slug", unique: true
|
||||
end
|
||||
|
||||
create_table "weapons", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||
t.string "name_en"
|
||||
t.string "name_jp"
|
||||
|
|
@ -1024,6 +1060,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
add_foreign_key "collection_weapons", "weapon_keys", column: "weapon_key2_id"
|
||||
add_foreign_key "collection_weapons", "weapon_keys", column: "weapon_key3_id"
|
||||
add_foreign_key "collection_weapons", "weapon_keys", column: "weapon_key4_id"
|
||||
add_foreign_key "collection_weapons", "weapon_stat_modifiers", column: "ax_modifier1_id"
|
||||
add_foreign_key "collection_weapons", "weapon_stat_modifiers", column: "ax_modifier2_id"
|
||||
add_foreign_key "collection_weapons", "weapon_stat_modifiers", column: "befoulment_modifier_id"
|
||||
add_foreign_key "collection_weapons", "weapons"
|
||||
add_foreign_key "crew_gw_participations", "crews"
|
||||
add_foreign_key "crew_gw_participations", "gw_events"
|
||||
|
|
@ -1049,6 +1088,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_21_210000) do
|
|||
add_foreign_key "grid_weapons", "collection_weapons"
|
||||
add_foreign_key "grid_weapons", "parties"
|
||||
add_foreign_key "grid_weapons", "weapon_keys", column: "weapon_key3_id"
|
||||
add_foreign_key "grid_weapons", "weapon_stat_modifiers", column: "ax_modifier1_id"
|
||||
add_foreign_key "grid_weapons", "weapon_stat_modifiers", column: "ax_modifier2_id"
|
||||
add_foreign_key "grid_weapons", "weapon_stat_modifiers", column: "befoulment_modifier_id"
|
||||
add_foreign_key "grid_weapons", "weapons"
|
||||
add_foreign_key "gw_crew_scores", "crew_gw_participations"
|
||||
add_foreign_key "gw_individual_scores", "crew_gw_participations"
|
||||
|
|
|
|||
Loading…
Reference in a new issue