Compare commits

..

No commits in common. "87782767f8323782f5a020deca7518e9738aeb04" and "9f74e6020e5f0897ac07de4bedfbc85a0986847a" have entirely different histories.

7 changed files with 32 additions and 123 deletions

View file

@ -121,16 +121,11 @@ class ItemsController < ApplicationController
def load_appearances def load_appearances
appearance_params = params[:with_appearances_for] appearance_params = params[:with_appearances_for]
return {} if appearance_params.blank? return {} if appearance_params.blank?
raise NotImplementedError if appearance_params[:alt_style_id].present?
if appearance_params[:alt_style_id].present? pet_type = Item::Search::Query.load_pet_type_by_color_and_species(
target = Item::Search::Query.load_alt_style_by_id(
appearance_params[:alt_style_id])
else
target = Item::Search::Query.load_pet_type_by_color_and_species(
appearance_params[:color_id], appearance_params[:species_id]) appearance_params[:color_id], appearance_params[:species_id])
end pet_type.appearances_for(@items.map(&:id), swf_asset_includes: [:zone])
target.appearances_for(@items.map(&:id), swf_asset_includes: [:zone])
end end
def search_error(e) def search_error(e)

View file

@ -6,31 +6,11 @@ class AltStyle < ApplicationRecord
has_many :swf_assets, through: :parent_swf_asset_relationships has_many :swf_assets, through: :parent_swf_asset_relationships
has_many :contributions, as: :contributed, inverse_of: :contributed has_many :contributions, as: :contributed, inverse_of: :contributed
scope :matching_name, ->(series_name, color_name, species_name) {
color = Color.find_by_name!(color_name)
species = Species.find_by_name!(species_name)
where(series_name:, color_id: color.id, species_id: species.id)
}
def name def name
I18n.translate('pet_types.human_name', color_human_name: color.human_name, I18n.translate('pet_types.human_name', color_human_name: color.human_name,
species_human_name: species.human_name) species_human_name: species.human_name)
end end
# If the series_name hasn't yet been set manually by support staff, show the
# string "<New?>" instead. But it won't be searchable by that string—that is,
# `fits:<New?>-faerie-draik` intentionally will not work, and the canonical
# filter name will be `fits:alt-style-IDNUMBER`, instead.
def series_name
self[:series_name] || "<New?>"
end
# You can use this to check whether `series_name` is returning the actual
# value or its placeholder value.
def has_real_series_name?
self[:series_name].present?
end
def adjective_name def adjective_name
"#{series_name} #{color.human_name}" "#{series_name} #{color.human_name}"
end end
@ -49,11 +29,6 @@ class AltStyle < ApplicationRecord
swf_asset.image_url swf_asset.image_url
end end
# Given a list of item IDs, return how they look on this alt style.
def appearances_for(item_ids, ...)
Item.appearances_for(item_ids, self, ...)
end
def biology=(biology) def biology=(biology)
# TODO: This is very similar to what `PetState` does, but like… much much # TODO: This is very similar to what `PetState` does, but like… much much
# more compact? Idk if I'm missing something, or if I was just that much # more compact? Idk if I'm missing something, or if I was just that much

View file

@ -495,34 +495,6 @@ class Item < ApplicationRecord
end end
end end
# Given a list of item IDs, return how they look on the given target (either
# a pet type or an alt style).
def self.appearances_for(item_ids, target, swf_asset_includes: [])
# First, load all the relationships for these items that also fit this
# body.
relationships = ParentSwfAssetRelationship.
includes(swf_asset: swf_asset_includes).
where(parent_type: "Item", parent_id: item_ids).
where(swf_asset: {body_id: [target.body_id, 0]})
pet_type_body = Appearance::Body.new(target.body_id, target.species)
all_pets_body = Appearance::Body.new(0, nil)
# Then, convert this into a hash from item ID to SWF assets.
assets_by_item_id = relationships.group_by(&:parent_id).
transform_values { |rels| rels.map(&:swf_asset) }
# Finally, for each item, return an appearance—even if it's empty!
item_ids.to_h do |item_id|
assets = assets_by_item_id.fetch(item_id, [])
fits_all_pets = assets.present? && assets.all? { |a| a.body_id == 0 }
body = fits_all_pets ? all_pets_body : pet_type_body
[item_id, Appearance.new(body, assets)]
end
end
def self.all_by_ids_or_children(ids, swf_assets) def self.all_by_ids_or_children(ids, swf_assets)
swf_asset_ids = [] swf_asset_ids = []
swf_assets_by_id = {} swf_assets_by_id = {}

View file

@ -62,8 +62,6 @@ class Item
when 'restricts' when 'restricts'
is_positive ? Filter.restricts(value) : Filter.not_restricts(value) is_positive ? Filter.restricts(value) : Filter.not_restricts(value)
when 'fits' when 'fits'
# First, try the `fits:blue-acara` case.
# NOTE: This will also work for `fits:"usuki girl-usul"`!
match = value.match(/^([^-]+)-([^-]+)$/) match = value.match(/^([^-]+)-([^-]+)$/)
if match.present? if match.present?
color_name, species_name = match.captures color_name, species_name = match.captures
@ -72,33 +70,6 @@ class Item
Filter.fits_pet_type(pet_type, color_name:, species_name:) : Filter.fits_pet_type(pet_type, color_name:, species_name:) :
Filter.not_fits_pet_type(pet_type, color_name:, species_name:) Filter.not_fits_pet_type(pet_type, color_name:, species_name:)
end end
# Next, try the `fits:alt-style-87305` case.
match = value.match(/^alt-style-([0-9]+)$/)
if match.present?
alt_style_id, = match.captures
alt_style = load_alt_style_by_id(alt_style_id)
return is_positive ?
Filter.fits_alt_style(alt_style) :
Filter.not_fits_alt_style(alt_style)
end
# Next, try the `fits:nostalgic-faerie-draik` case.
# NOTE: This will also work for `fits:"nostalgic-usuki girl-usul"`!
match = value.match(/^([^-]+)-([^-]+)-([^-]+)$/)
if match.present?
series_name, color_name, species_name = match.captures
alt_style = load_alt_style_by_name(
series_name, color_name, species_name)
return is_positive ?
Filter.fits_alt_style(alt_style) :
Filter.not_fits_alt_style(alt_style)
end
# TODO: We could make `fits:acara` an alias for `species:acara`, or
# even the primary syntax?
# If none of these cases work, raise an error.
raise_search_error "not_found.fits_target", value: value raise_search_error "not_found.fits_target", value: value
when 'species' when 'species'
begin begin
@ -205,19 +176,10 @@ class Item
end end
end end
def self.load_alt_style_by_name(series_name, color_name, species_name)
begin
AltStyle.matching_name(series_name, color_name, species_name).first!
rescue ActiveRecord::RecordNotFound
raise_search_error "not_found.alt_style",
filter_text: "#{series_name}-#{color_name}-#{species_name}"
end
end
def self.load_alt_style_by_id(alt_style_id) def self.load_alt_style_by_id(alt_style_id)
begin begin
AltStyle.find(alt_style_id) AltStyle.find(alt_style_id)
rescue ActiveRecord::RecordNotFound rescue
raise_search_error "not_found.alt_style", raise_search_error "not_found.alt_style",
filter_text: "alt-style-#{alt_style_id}" filter_text: "alt-style-#{alt_style_id}"
end end
@ -364,18 +326,8 @@ class Item
end end
def self.alt_style_to_filter_text(alt_style) def self.alt_style_to_filter_text(alt_style)
# If the real series name has been set in the database by support
# staff, use that for the canonical filter text for this alt style.
# Otherwise, represent this alt style by ID.
if alt_style.has_real_series_name?
series_name = alt_style.series_name.downcase
color_name = alt_style.color.name.downcase
species_name = alt_style.species.name.downcase
"#{series_name}-#{color_name}-#{species_name}"
else
"alt-style-#{alt_style.id}" "alt-style-#{alt_style.id}"
end end
end end
end end
end end
end

View file

@ -169,9 +169,30 @@ class PetType < ApplicationRecord
}.first }.first
end end
# Given a list of item IDs, return how they look on this pet type. def appearances_for(item_ids, swf_asset_includes: [])
def appearances_for(item_ids, ...) # First, load all the relationships for these items that also fit this
Item.appearances_for(item_ids, self, ...) # body.
relationships = ParentSwfAssetRelationship.
includes(swf_asset: swf_asset_includes).
where(parent_type: "Item", parent_id: item_ids).
where(swf_asset: {body_id: [body_id, 0]})
pet_type_body = Item::Appearance::Body.new(body_id, species)
all_pets_body = Item::Appearance::Body.new(0, nil)
# Then, convert this into a hash from item ID to SWF assets.
assets_by_item_id = relationships.group_by(&:parent_id).
transform_values { |rels| rels.map(&:swf_asset) }
# Finally, for each item, return an appearance—even if it's empty!
item_ids.to_h do |item_id|
assets = assets_by_item_id.fetch(item_id, [])
fits_all_pets = assets.present? && assets.all? { |a| a.body_id == 0 }
body = fits_all_pets ? all_pets_body : pet_type_body
[item_id, Item::Appearance.new(body, assets)]
end
end end
def self.all_by_ids_or_children(ids, pet_states) def self.all_by_ids_or_children(ids, pet_states)

View file

@ -1,6 +0,0 @@
class ChangeDefaultForAltStylesSeriesName < ActiveRecord::Migration[7.1]
def change
change_column_null :alt_styles, :series_name, true
change_column_default :alt_styles, :series_name, from: "<New?>", to: nil
end
end

View file

@ -10,14 +10,14 @@
# #
# 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.1].define(version: 2024_02_27_233743) do ActiveRecord::Schema[7.1].define(version: 2024_02_27_231815) do
create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t| create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
t.integer "species_id", null: false t.integer "species_id", null: false
t.integer "color_id", null: false t.integer "color_id", null: false
t.integer "body_id", null: false t.integer "body_id", null: false
t.datetime "created_at", precision: nil, null: false t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false
t.string "series_name" t.string "series_name", default: "<New?>", null: false
t.index ["color_id"], name: "index_alt_styles_on_color_id" t.index ["color_id"], name: "index_alt_styles_on_color_id"
t.index ["species_id"], name: "index_alt_styles_on_species_id" t.index ["species_id"], name: "index_alt_styles_on_species_id"
end end