hensei-api/app/models/collection_character.rb

92 lines
No EOL
3.1 KiB
Ruby

class CollectionCharacter < ApplicationRecord
belongs_to :user
belongs_to :character
belongs_to :awakening, optional: true
before_save :add_default_awakening
validates :character_id, uniqueness: { scope: :user_id,
message: "already exists in your collection" }
validates :uncap_level, inclusion: { in: 0..5 }
validates :transcendence_step, inclusion: { in: 0..10 }
validates :awakening_level, inclusion: { in: 1..10 }
validate :validate_rings
validate :validate_awakening_compatibility
validate :validate_awakening_level
validate :validate_transcendence_requirements
scope :by_element, ->(element) { joins(:character).where(characters: { element: element }) }
scope :by_rarity, ->(rarity) { joins(:character).where(characters: { rarity: rarity }) }
scope :by_race, ->(races) {
joins(:character).where('characters.race1 IN (?) OR characters.race2 IN (?)', races, races)
}
scope :by_proficiency, ->(proficiencies) {
joins(:character).where('characters.proficiency1 IN (?) OR characters.proficiency2 IN (?)', proficiencies, proficiencies)
}
scope :by_gender, ->(genders) { joins(:character).where(characters: { gender: genders }) }
scope :transcended, -> { where('transcendence_step > 0') }
scope :with_awakening, -> { where.not(awakening_id: nil) }
# Sorting scopes
scope :sorted_by, ->(sort_key) {
case sort_key
when 'name_asc'
joins(:character).order('characters.name_en ASC NULLS LAST')
when 'name_desc'
joins(:character).order('characters.name_en DESC NULLS LAST')
when 'element_asc'
joins(:character).order('characters.element ASC')
when 'element_desc'
joins(:character).order('characters.element DESC')
when 'proficiency_asc'
joins(:character).order('characters.proficiency1 ASC')
when 'proficiency_desc'
joins(:character).order('characters.proficiency1 DESC')
else
order(created_at: :desc) # Default: newest first
end
}
def blueprint
Api::V1::CollectionCharacterBlueprint
end
private
def validate_rings
[ring1, ring2, ring3, ring4, earring].each_with_index do |ring, index|
next unless ring['modifier'].present? || ring['strength'].present?
if ring['modifier'].blank? || ring['strength'].blank?
errors.add(:base, "Ring #{index + 1} must have both modifier and strength")
end
end
end
def validate_awakening_compatibility
return unless awakening.present?
unless awakening.object_type == 'Character'
errors.add(:awakening, "must be a character awakening")
end
end
def validate_awakening_level
if awakening_level.present? && awakening_level > 1 && awakening_id.blank?
errors.add(:awakening_level, "cannot be set without an awakening")
end
end
def validate_transcendence_requirements
if transcendence_step.present? && transcendence_step > 0 && uncap_level < 5
errors.add(:transcendence_step, "requires uncap level 5 (current: #{uncap_level})")
end
end
def add_default_awakening
return unless awakening.nil?
self.awakening = Awakening.where(slug: 'character-balanced').sole
end
end