add season/series validations, scopes, helpers to Character

This commit is contained in:
Justin Edmund 2025-12-02 04:09:55 -08:00
parent 24d8d20ff8
commit afa1c5154f

View file

@ -41,6 +41,30 @@ class Character < ApplicationRecord
{ slug: 'character-multi', name_en: 'Multiattack', name_jp: '連続攻撃', order: 3 }
].freeze
# Non-gachable series (characters that must be recruited, not pulled)
NON_GACHABLE_SERIES = [
GranblueEnums::CHARACTER_SERIES[:Eternal],
GranblueEnums::CHARACTER_SERIES[:Evoker],
GranblueEnums::CHARACTER_SERIES[:Saint],
GranblueEnums::CHARACTER_SERIES[:Event],
GranblueEnums::CHARACTER_SERIES[:Collab]
].freeze
# Validations
validates :season,
numericality: { only_integer: true },
inclusion: { in: GranblueEnums::CHARACTER_SEASONS.values },
allow_nil: true
validate :validate_series_values
# Scopes
scope :by_season, ->(season) { where(season: season) }
scope :by_series, ->(series) { where('? = ANY(series)', series) }
scope :gachable, -> { where(gacha_available: true) }
scope :recruitable, -> { where(gacha_available: false) }
scope :seasonal, -> { where.not(season: [nil, GranblueEnums::CHARACTER_SEASONS[:Standard]]) }
def blueprint
CharacterBlueprint
end
@ -48,4 +72,36 @@ class Character < ApplicationRecord
def display_resource(character)
character.name_en
end
# Helper methods
def seasonal?
season.present? && season != GranblueEnums::CHARACTER_SEASONS[:Standard]
end
def gachable?
gacha_available
end
def season_name
return nil if season.nil?
GranblueEnums::CHARACTER_SEASONS.key(season)&.to_s
end
def series_names
return [] if series.blank?
series.filter_map { |s| GranblueEnums::CHARACTER_SERIES.key(s)&.to_s }
end
private
def validate_series_values
return if series.blank?
invalid_values = series.reject { |s| GranblueEnums::CHARACTER_SERIES.values.include?(s) }
return if invalid_values.empty?
errors.add(:series, "contains invalid values: #{invalid_values.join(', ')}")
end
end