[WV2] Filter colors, using advanced fallbacks
This commit is contained in:
parent
ddb89dc2fa
commit
58fabad3c2
5 changed files with 73 additions and 10 deletions
|
|
@ -78,17 +78,24 @@ class OutfitsController < ApplicationController
|
|||
end
|
||||
|
||||
def new_v2
|
||||
@colors = Color.alphabetical
|
||||
@species = Species.alphabetical
|
||||
|
||||
# Get selected species and color from params, or default to Blue Acara
|
||||
species_id = params[:species] || Species.find_by_name("Acara")&.id
|
||||
color_id = params[:color] || Color.find_by_name("Blue")&.id
|
||||
@selected_species = params[:species] ? Species.find_by_id(params[:species]) : Species.find_by_name("Acara")
|
||||
@selected_color = params[:color] ? Color.find_by_id(params[:color]) : Color.find_by_name("Blue")
|
||||
|
||||
# Find the pet type (species+color combination)
|
||||
@selected_species = Species.find_by(id: species_id)
|
||||
@selected_color = Color.find_by(id: color_id)
|
||||
@pet_type = PetType.find_by(species_id: species_id, color_id: color_id) if @selected_species && @selected_color
|
||||
# Load valid colors for the selected species (colors that have existing pet types)
|
||||
@species = Species.alphabetical
|
||||
@colors = @selected_species.compatible_colors
|
||||
|
||||
# Find the best pet type for this species+color combo
|
||||
# If the exact combo doesn't exist, this will fall back to a simple color
|
||||
@pet_type = PetType.for_species_and_color(
|
||||
species_id: @selected_species.id,
|
||||
color_id: @selected_color.id
|
||||
)
|
||||
|
||||
# Use the pet type's actual color as the selected color
|
||||
# (might differ from requested color if we fell back to a simple color)
|
||||
@selected_color = @pet_type&.color
|
||||
|
||||
# Load items from the objects[] parameter
|
||||
item_ids = params[:objects] || []
|
||||
|
|
|
|||
|
|
@ -48,6 +48,26 @@ class PetType < ApplicationRecord
|
|||
random_pet_types
|
||||
end
|
||||
|
||||
# Given a species ID and color ID, return the best matching PetType.
|
||||
#
|
||||
# If the exact species+color combo exists, return it.
|
||||
# Otherwise, find the best fallback for that species:
|
||||
# - Prefer the requested color if available
|
||||
# - Otherwise prefer simple colors (basic > standard > alphabetical)
|
||||
#
|
||||
# This matches the wardrobe behavior where we automatically switch to a valid
|
||||
# color when the user selects a species that doesn't support their current color.
|
||||
#
|
||||
# Returns the PetType, or nil if no pet types exist for this species.
|
||||
def self.for_species_and_color(species_id:, color_id:)
|
||||
return nil if species_id.nil?
|
||||
|
||||
where(species_id: species_id)
|
||||
.preferring_color(color_id)
|
||||
.preferring_simple
|
||||
.first
|
||||
end
|
||||
|
||||
def as_json(options={})
|
||||
super({
|
||||
only: [:id],
|
||||
|
|
|
|||
|
|
@ -34,4 +34,13 @@ class Species < ApplicationRecord
|
|||
def self.param_to_id(param)
|
||||
param.match?(/\A\d+\Z/) ? param.to_i : find_by_name!(param).id
|
||||
end
|
||||
|
||||
# Get all colors that are compatible with this species (have pet types)
|
||||
# Returns an ActiveRecord::Relation of Color records
|
||||
def compatible_colors
|
||||
Color.alphabetical
|
||||
.joins(:pet_types)
|
||||
.where(pet_types: { species_id: id })
|
||||
.distinct
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -38,4 +38,23 @@ RSpec.describe PetType do
|
|||
expect(PetType.find_by_param!("123-456")).to eq pet_types(:newcolor_newspecies)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".for_species_and_color" do
|
||||
it('returns the exact match when it exists') do
|
||||
result = PetType.for_species_and_color(species_id: species(:acara), color_id: colors(:blue))
|
||||
expect(result).to eq pet_types(:blue_acara)
|
||||
end
|
||||
|
||||
it('returns nil when species is nil') do
|
||||
result = PetType.for_species_and_color(species_id: nil, color_id: colors(:blue))
|
||||
expect(result).to be_nil
|
||||
end
|
||||
|
||||
it('falls back to a simple color when exact match does not exist') do
|
||||
# Request a species that exists but with a color that might not
|
||||
# It should fall back to a basic/standard color for that species
|
||||
result = PetType.for_species_and_color(species_id: species(:acara), color_id: 999)
|
||||
expect(result).to eq pet_types(:blue_acara)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
require_relative '../rails_helper'
|
||||
|
||||
RSpec.describe Species do
|
||||
fixtures :species
|
||||
fixtures :species, :colors
|
||||
|
||||
describe "#valid_colors_for_species" do
|
||||
it('returns colors that have pet types for the species') do
|
||||
# The Blue Acara exists in fixtures, as does a "Color #123 Acara", which we'll ignore.
|
||||
compatible_colors = species(:acara).compatible_colors
|
||||
expect(compatible_colors.map(&:id)).to eq [8]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_param' do
|
||||
it("uses name when possible") do
|
||||
|
|
|
|||
Loading…
Reference in a new issue