Stop orphaning hangers when deleting lists

Idk if this used to be different or what, but it looks like the current
behavior is: if you delete a closet list, it'll leave the hangers
present, but Classic DTI would not show them anywhere; but Impress 2020
(until recently) would crash about it.

Now, we use `dependent: :destroy` to delete the hangers when you delete
the list (which I think makes sense, and is different than what I
decided in the past but that's ok, and is what the current behavior
*looks* like to people!), and we add a migration that deletes orphaned
hangers.

The migration also outputs the deleted hangers as JSON, for us to hold
onto in case we made a mistake! I'm also backing up the database in
advance of running this migration, just in case we gotta roll back HARD!
This commit is contained in:
Emi Matchu 2023-10-24 15:35:21 -07:00
parent 661fbd2d03
commit b8a8cb9b20
4 changed files with 22 additions and 10 deletions

View file

@ -1,6 +1,6 @@
class ClosetList < ApplicationRecord class ClosetList < ApplicationRecord
belongs_to :user belongs_to :user
has_many :hangers, :class_name => 'ClosetHanger', :foreign_key => 'list_id' has_many :hangers, class_name: 'ClosetHanger', foreign_key: 'list_id', dependent: :destroy
validates :name, :presence => true, :uniqueness => {:scope => :user_id} validates :name, :presence => true, :uniqueness => {:scope => :user_id}
validates :user, :presence => true validates :user, :presence => true

View file

@ -0,0 +1,12 @@
class DeleteOrphanedClosetHangers < ActiveRecord::Migration[7.0]
def up
orphaned_hangers = ClosetHanger.left_outer_joins(:list).
where("closet_hangers.list_id IS NOT NULL").where("closet_lists.id IS NULL")
puts orphaned_hangers.to_json
orphaned_hangers.delete_all
end
def down
raise ActiveRecord::IrreversibleMigration, "The orphaned hangers are already gone!"
end
end

View file

@ -11,7 +11,7 @@
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_08_07_005748) do ActiveRecord::Schema[7.0].define(version: 2023_08_07_005748) do
create_table "users", id: { type: :integer, unsigned: true }, charset: "utf8", force: :cascade do |t| create_table "users", id: { type: :integer, unsigned: true }, charset: "utf8mb3", force: :cascade do |t|
t.string "name", limit: 20, null: false t.string "name", limit: 20, null: false
t.string "encrypted_password", limit: 64, null: false t.string "encrypted_password", limit: 64, null: false
t.string "email", limit: 50, null: false t.string "email", limit: 50, null: false

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_08_02_195548) do ActiveRecord::Schema[7.0].define(version: 2023_10_24_221826) do
create_table "auth_servers", id: :integer, charset: "latin1", force: :cascade do |t| create_table "auth_servers", id: :integer, charset: "latin1", force: :cascade do |t|
t.string "short_name", limit: 10, null: false t.string "short_name", limit: 10, null: false
t.string "name", limit: 40, null: false t.string "name", limit: 40, null: false
@ -114,11 +114,11 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_02_195548) do
t.index ["outfit_id", "is_worn"], name: "index_item_outfit_relationships_on_outfit_id_and_is_worn" t.index ["outfit_id", "is_worn"], name: "index_item_outfit_relationships_on_outfit_id_and_is_worn"
end end
create_table "item_translations", id: :integer, charset: "latin1", force: :cascade do |t| create_table "item_translations", id: :integer, charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
t.integer "item_id" t.integer "item_id"
t.string "locale" t.string "locale"
t.string "name" t.string "name"
t.text "description" t.text "description", size: :medium
t.string "rarity" t.string "rarity"
t.datetime "created_at", precision: nil t.datetime "created_at", precision: nil
t.datetime "updated_at", precision: nil t.datetime "updated_at", precision: nil
@ -128,7 +128,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_02_195548) do
t.index ["name"], name: "index_item_translations_name" t.index ["name"], name: "index_item_translations_name"
end end
create_table "items", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t| create_table "items", id: :integer, charset: "utf8mb3", collation: "utf8mb3_unicode_ci", force: :cascade do |t|
t.text "zones_restrict", null: false t.text "zones_restrict", null: false
t.text "thumbnail_url", size: :medium, null: false t.text "thumbnail_url", size: :medium, null: false
t.string "category", limit: 50 t.string "category", limit: 50
@ -187,7 +187,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_02_195548) do
t.index ["user_id"], name: "index_outfits_on_user_id" t.index ["user_id"], name: "index_outfits_on_user_id"
end end
create_table "parents_swf_assets", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t| create_table "parents_swf_assets", id: :integer, charset: "utf8mb3", collation: "utf8mb3_unicode_ci", force: :cascade do |t|
t.integer "parent_id", limit: 3, null: false t.integer "parent_id", limit: 3, null: false
t.integer "swf_asset_id", limit: 3, null: false t.integer "swf_asset_id", limit: 3, null: false
t.string "parent_type", limit: 8, null: false t.string "parent_type", limit: 8, null: false
@ -202,7 +202,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_02_195548) do
t.datetime "created_at", precision: nil, null: false t.datetime "created_at", precision: nil, null: false
end end
create_table "pet_states", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t| create_table "pet_states", id: :integer, charset: "utf8mb3", collation: "utf8mb3_unicode_ci", force: :cascade do |t|
t.integer "pet_type_id", limit: 3, null: false t.integer "pet_type_id", limit: 3, null: false
t.text "swf_asset_ids", null: false t.text "swf_asset_ids", null: false
t.boolean "female" t.boolean "female"
@ -214,7 +214,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_02_195548) do
t.index ["pet_type_id"], name: "pet_states_pet_type_id" t.index ["pet_type_id"], name: "pet_states_pet_type_id"
end end
create_table "pet_types", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t| create_table "pet_types", id: :integer, charset: "utf8mb3", collation: "utf8mb3_unicode_ci", force: :cascade do |t|
t.integer "color_id", limit: 1, null: false t.integer "color_id", limit: 1, null: false
t.integer "species_id", limit: 1, null: false t.integer "species_id", limit: 1, null: false
t.datetime "created_at", precision: nil, null: false t.datetime "created_at", precision: nil, null: false
@ -248,7 +248,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_02_195548) do
t.index ["species_id"], name: "index_species_translations_on_species_id" t.index ["species_id"], name: "index_species_translations_on_species_id"
end end
create_table "swf_assets", id: :integer, charset: "utf8", collation: "utf8_unicode_ci", force: :cascade do |t| create_table "swf_assets", id: :integer, charset: "utf8mb3", collation: "utf8mb3_unicode_ci", force: :cascade do |t|
t.string "type", limit: 7, null: false t.string "type", limit: 7, null: false
t.integer "remote_id", limit: 3, null: false t.integer "remote_id", limit: 3, null: false
t.text "url", size: :medium, null: false t.text "url", size: :medium, null: false