update character model and blueprint for series lookup

This commit is contained in:
Justin Edmund 2025-12-14 11:58:30 -08:00
parent ead6f45802
commit c4e42b0968
2 changed files with 86 additions and 3 deletions

View file

@ -12,12 +12,31 @@ module Api
fields :granblue_id, :character_id, :rarity,
:element, :gender, :special, :season,
:series, :gacha_available
:gacha_available
field :season_name do |c|
c.season_name
end
field :series do |c|
# Use new lookup table if available
if c.character_series_records.any?
c.character_series_records.ordered.map do |cs|
{
id: cs.id,
slug: cs.slug,
name: {
en: cs.name_en,
ja: cs.name_jp
}
}
end
else
# Legacy fallback - return integer array
c.series
end
end
field :series_names do |c|
c.series_names
end

View file

@ -3,6 +3,9 @@
class Character < ApplicationRecord
include PgSearch::Model
has_many :character_series_memberships, dependent: :destroy
has_many :character_series_records, through: :character_series_memberships, source: :character_series
multisearchable against: %i[name_en name_jp],
additional_attributes: lambda { |character|
{
@ -89,9 +92,70 @@ class Character < ApplicationRecord
end
def series_names
return [] if series.blank?
# Use new lookup table if available
if character_series_records.loaded? ? character_series_records.any? : character_series_records.exists?
character_series_records.ordered.pluck(:name_en)
elsif series.present?
# Legacy fallback
series.filter_map { |s| GranblueEnums::CHARACTER_SERIES.key(s)&.to_s }
else
[]
end
end
series.filter_map { |s| GranblueEnums::CHARACTER_SERIES.key(s)&.to_s }
def series_objects
character_series_records.ordered
end
def series_slugs
character_series_records.pluck(:slug)
end
# Mapping from legacy integer values to slugs
LEGACY_SERIES_TO_SLUG = {
1 => 'standard',
2 => 'grand',
3 => 'zodiac',
4 => 'promo',
5 => 'collab',
6 => 'eternal',
7 => 'evoker',
8 => 'saint',
9 => 'fantasy',
10 => 'summer',
11 => 'yukata',
12 => 'valentine',
13 => 'halloween',
14 => 'formal',
15 => 'event'
}.freeze
# Virtual attribute to set character_series by array of IDs, slugs, or legacy integers
# Supports multiple formats for flexibility during migration
def series=(values)
return if values.blank?
# Ensure it's an array
values = Array(values)
values.each do |value|
next if value.blank?
# Try to find the series record
series_record = if value.is_a?(Integer)
# Legacy integer - convert to slug first
slug = LEGACY_SERIES_TO_SLUG[value]
slug ? CharacterSeries.find_by(slug: slug) : nil
else
# String - try UUID first, then slug
CharacterSeries.find_by(id: value) || CharacterSeries.find_by(slug: value)
end
next unless series_record
# Create membership if it doesn't exist
character_series_memberships.find_or_initialize_by(character_series: series_record)
end
end
private