class OutfitsController < ApplicationController before_action :find_authorized_outfit, :only => [:update, :destroy] def create @outfit = Outfit.new(outfit_params) @outfit.user = current_user if @outfit.save render :json => @outfit else render_outfit_errors end end def edit render "outfits/edit", layout: false end def index if user_signed_in? @outfits = current_user.outfits. includes(:item_outfit_relationships, {:pet_state => :pet_type}). wardrobe_order respond_to do |format| format.html { render } format.json { render :json => @outfits } end else respond_to do |format| format.html { redirect_to new_auth_user_session_path(:return_to => request.fullpath) } format.json { render :json => [] } end end end def destroy @outfit.destroy respond_to do |format| format.html { flash[:notice] = t('outfits.destroy.success', :outfit_name => @outfit.name) redirect_to current_user_outfits_path } format.json { render :json => true } end end def new @colors = Color.alphabetical @species = Species.alphabetical newest_items = Item.newest.limit(18) @newest_modeled_items, @newest_unmodeled_items = newest_items.partition(&:predicted_fully_modeled?) @newest_unmodeled_items_predicted_missing_species_by_color = {} @newest_unmodeled_items_predicted_modeled_ratio = {} @newest_unmodeled_items.each do |item| h = item.predicted_missing_nonstandard_body_ids_by_species_by_color standard_body_ids_by_species = item. predicted_missing_standard_body_ids_by_species if standard_body_ids_by_species.present? h[:standard] = standard_body_ids_by_species end @newest_unmodeled_items_predicted_missing_species_by_color[item] = h @newest_unmodeled_items_predicted_modeled_ratio[item] = item.predicted_modeled_ratio end @species_count = Species.count @latest_contribution = Contribution.recent.first Contribution.preload_contributeds_and_parents([@latest_contribution].compact) @neopets_usernames = user_signed_in? ? current_user.neopets_usernames : [] @campaign = Fundraising::Campaign.current rescue nil end def new_v2 # Get selected species and color from params, or default to Blue Acara @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") # 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] || [] items = Item.where(id: item_ids) # Build the outfit @outfit = Outfit.new( pet_state: @pet_type&.canonical_pet_state, worn_items: items, ) # Preload the manifests for all visible layers, so they load efficiently # in parallel rather than sequentially when rendering SwfAsset.preload_manifests(@outfit.visible_layers) # Handle search mode @search_mode = params[:q].present? if @search_mode search_filters = build_search_filters(params[:q], @outfit) query_params = ActionController::Parameters.new( search_filters.each_with_index.map { |filter, i| [i.to_s, filter] }.to_h ) @query = Item::Search::Query.from_params(query_params, current_user) @search_results = @query.results.paginate(page: params.dig(:q, :page), per_page: 30) end render layout: false end def show @outfit = Outfit.find(params[:id]) respond_to do |format| format.html { render "outfits/edit", layout: false } format.json { render json: @outfit } end end def start # Start URLs are always in English, so let's make sure we search in # English. I18n.locale = I18n.default_locale @species = Species.find_by_name params[:species_name] @color = Color.find_by_name params[:color_name] if @species && @color redirect_to wardrobe_path(:species => @species.id, :color => @color.id) else not_found('species/color') end end def update if @outfit.update(outfit_params) render :json => @outfit else render_outfit_errors end end private def outfit_params params.require(:outfit).permit( :name, :starred, :alt_style_id, item_ids: {worn: [], closeted: []}, biology: [:species_id, :color_id, :pose, :pet_state_id]) end def find_authorized_outfit raise ActiveRecord::RecordNotFound unless user_signed_in? @outfit = current_user.outfits.find(params[:id]) end def render_outfit_errors render :json => {:errors => @outfit.errors, :full_error_messages => @outfit.errors.full_messages}, :status => :bad_request end def build_search_filters(query_params, outfit) filters = [] # Add name filter if present if query_params[:name].present? filters << { key: "name", value: query_params[:name] } end # Add item kind filter if present if query_params[:item_kind].present? case query_params[:item_kind] when "nc" filters << { key: "is_nc", value: "true" } when "np" filters << { key: "is_np", value: "true" } when "pb" filters << { key: "is_pb", value: "true" } end end # Add zone filter if present if query_params[:zone].present? filters << { key: "occupied_zone_set_name", value: query_params[:zone] } end # Always add auto-filter for items that fit the current pet pet_type = outfit.pet_type if pet_type fit_filter = { key: "fits", value: { species_id: pet_type.species_id.to_s, color_id: pet_type.color_id.to_s } } # Include alt_style_id if present if outfit.alt_style_id.present? fit_filter[:value][:alt_style_id] = outfit.alt_style_id.to_s end filters << fit_filter end filters end end