Compare commits

..

2 commits

Author SHA1 Message Date
857cb547ed Add Item#dyeworks_base_item database field, and populate it
In this change, instead of *always* inferring the Dyeworks base item
from the item name at runtime, we now have a database field that tracks
it, and auto-populates whenever an item *seems* to need a Dyeworks base
item but doesn't have one yet.

This will enable us to set the base item manually in cases where it
can't be inferred, and load Dyeworks base items for the Item Getting
Guide in one query with `includes(:dyeworks_base_item)`.

This migration does a bit more of the fix-em-up scripting work *in* the
migration itself than I usually do, mainly because there's so much in
this one that I think being extra-explicit is useful. We make sure to
do it gracefully though!
2024-06-07 20:10:06 -07:00
68cb44d159 Add logic to infer the base for Dyeworks items
This works for most of the current 1,094 Dyeworks items! But there are
a few exceptions, for cases where the base item name is not quite the
same (e.g. the Dyeworks version is more concise). Maybe we'll add a
database field to override this?

- Dyeworks Baby Blue: Baby Valentine Jumper
- Dyeworks Baby Pink: Baby Valentine Jumper
- Dyeworks Black: Field of Flowers
- Dyeworks Black: Games Master Challenge 2010 Lulu Shirt
- Dyeworks Blue: Field of Flowers
- Dyeworks Blue: Stars and Glitter Facepaint
- Dyeworks Brown: Hanging Winter Candles Garland
- Dyeworks Green: Stars and Glitter Facepaint
- Dyeworks Magenta: Lovely Berry Blush
- Dyeworks Orange & Pink: Winter Lights Effects
- Dyeworks Orange: Games Master Challenge 2010 Lulu Shirt
- Dyeworks Peach: Lovely Berry Blush
- Dyeworks Purple: Baby Valentine Jumper
- Dyeworks Purple: Games Master Challenge 2010 Lulu Shirt
- Dyeworks Purple: Hanging Winter Candles Garland
- Dyeworks Purple: Stars and Glitter Facepaint
- Dyeworks Red & Green: Winter Lights Effects
- Dyeworks Silver: Hanging Winter Candles Garland
- Dyeworks Soft Pink: Lovely Berry Blush
- Dyeworks Yellow & Magenta: Winter Lights Effects
- Dyeworks Yellow: Field of Flowers
2024-06-07 19:35:43 -07:00
3 changed files with 118 additions and 1 deletions

View file

@ -14,6 +14,9 @@ class Item < ApplicationRecord
has_one :nc_mall_record
has_many :parent_swf_asset_relationships, :as => :parent
has_many :swf_assets, :through => :parent_swf_asset_relationships
belongs_to :dyeworks_base_item, class_name: "Item",
default: -> { inferred_dyeworks_base_item }, optional: true
attr_writer :current_body_id, :owned, :wanted
@ -195,6 +198,26 @@ class Item < ApplicationRecord
nc_mall_record.present?
end
def dyeworks?
dyeworks_base_item.present?
end
DYEWORKS_NAME_PATTERN = %r{
^(
# Most Dyeworks items have a colon in the name.
Dyeworks\s+(?<color>.+?:)\s*(?<base>.+)
|
# But sometimes they omit it. If so, assume the first word is the color!
Dyeworks\s+(?<color>\S+)\s*(?<base>.+)
)$
}x
def inferred_dyeworks_base_item
name_match = name.match(DYEWORKS_NAME_PATTERN)
return nil if name_match.nil?
Item.find_by_name(name_match["base"])
end
def owned?
@owned || false
end

View file

@ -0,0 +1,91 @@
class AddDyeworksBaseItemIdToItems < ActiveRecord::Migration[7.1]
def change
add_reference :items, :dyeworks_base_item, type: :integer,
foreign_key: {to_table: :items}
# Find Dyeworks items, and fill in their base item field. (The Item model
# is configured to try to infer this when saving Dyeworks-seeming items
# with no matching base item yet.)
#
# Some item names that exist right now are known to not fit the pattern, so
# we try to set them manually if present in this copy of the database.
reversible do |direction|
direction.up do
dyeworks_items = Item.where("name LIKE ?", "Dyeworks %").to_a
puts "Found #{dyeworks_items.size} Dyeworks items, " +
"inferring base items…"
dyeworks_items.each(&:save!)
num_successes = dyeworks_items.select(&:dyeworks?).size
puts "Inferred Dyeworks base item for #{num_successes} items"
set_manually "Baby Valentine Jumper and Shirt",
"Dyeworks Baby Blue: Baby Valentine Jumper",
"Dyeworks Baby Pink: Baby Valentine Jumper",
"Dyeworks Purple: Baby Valentine Jumper"
set_manually "Field of Flowers Foreground",
"Dyeworks Black: Field of Flowers",
"Dyeworks Blue: Field of Flowers",
"Dyeworks Yellow: Field of Flowers"
set_manually "2010 Games Master Challenge NC Challenge Lulu Shirt",
"Dyeworks Black: Games Master Challenge 2010 Lulu Shirt",
"Dyeworks Orange: Games Master Challenge 2010 Lulu Shirt",
"Dyeworks Purple: Games Master Challenge 2010 Lulu Shirt"
set_manually "Stars and Glitter Face Paint",
"Dyeworks Blue: Stars and Glitter Facepaint",
"Dyeworks Green: Stars and Glitter Facepaint",
"Dyeworks Purple: Stars and Glitter Facepaint"
set_manually "Hanging Winter Candle Garland",
"Dyeworks Brown: Hanging Winter Candles Garland",
"Dyeworks Purple: Hanging Winter Candles Garland",
"Dyeworks Silver: Hanging Winter Candles Garland"
set_manually "Lovely Berry Blush Makeup",
"Dyeworks Magenta: Lovely Berry Blush",
"Dyeworks Peach: Lovely Berry Blush",
"Dyeworks Soft Pink: Lovely Berry Blush"
set_manually "Winter Lights Effect",
"Dyeworks Orange & Pink: Winter Lights Effects",
"Dyeworks Red & Green: Winter Lights Effects",
"Dyeworks Yellow & Magenta: Winter Lights Effects"
danglers = Item.where("name LIKE ?", "Dyeworks %").
where(dyeworks_base_item_id: nil).to_a
puts "There are now #{danglers.size} Dyeworks-seeming items in the " +
"database without a matching base item."
danglers.each do |dangler|
puts "- #{dangler.name}"
end
end
end
end
private
def set_manually(base_item_name, *dyeworks_item_names)
base_item = Item.find_by_name(base_item_name)
if base_item.nil?
puts "Skipping all manual Dyeworks for base item #{base_item}: not found"
return
end
dyeworks_item_names.each do |dyeworks_item_name|
dyeworks_item = Item.find_by_name(dyeworks_item_name)
if dyeworks_item.nil?
puts "Skipping manual Dyeworks for #{base_item_name} -> " +
"#{dyeworks_item_name}: not found"
next
end
dyeworks_item.update!(dyeworks_base_item: base_item)
puts "Manually assigned Dyeworks #{base_item_name} -> " +
"#{dyeworks_item_name}"
end
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2024_06_03_181855) do
ActiveRecord::Schema[7.1].define(version: 2024_06_08_022149) do
create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
t.integer "species_id", null: false
t.integer "color_id", null: false
@ -136,6 +136,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_06_03_181855) do
t.string "name", null: false
t.text "description", size: :medium, null: false
t.string "rarity", default: "", null: false
t.integer "dyeworks_base_item_id"
t.index ["dyeworks_base_item_id"], name: "index_items_on_dyeworks_base_item_id"
t.index ["modeling_status_hint", "created_at", "id"], name: "items_modeling_status_hint_and_created_at_and_id"
t.index ["modeling_status_hint", "created_at"], name: "items_modeling_status_hint_and_created_at"
t.index ["modeling_status_hint", "id"], name: "items_modeling_status_hint_and_id"
@ -292,6 +294,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_06_03_181855) do
add_foreign_key "alt_styles", "colors"
add_foreign_key "alt_styles", "species"
add_foreign_key "items", "items", column: "dyeworks_base_item_id"
add_foreign_key "nc_mall_records", "items"
add_foreign_key "outfits", "alt_styles"
end