Emi Matchu
a03ae90697
It was a bit tricky to figure out the right API for this, since I'm looking ahead to the possibility of splitting these across multiple pages with more detail, like we do in DTI 2020. What I like about this API is that the caller gets to apply, or not apply, whatever scopes they want to the underlying hanger set (like `includes` or `order`), without violating the usual syntax by e.g. passing it as a parameter to a method.
146 lines
4.2 KiB
Ruby
146 lines
4.2 KiB
Ruby
class ItemsController < ApplicationController
|
|
before_action :set_query
|
|
rescue_from Item::Search::Error, :with => :search_error
|
|
|
|
def index
|
|
if @query
|
|
begin
|
|
if params[:per_page]
|
|
per_page = params[:per_page].to_i
|
|
per_page = 50 if per_page && per_page > 50
|
|
else
|
|
per_page = 30
|
|
end
|
|
# Note that we sort by name by hand, since we might have to use
|
|
# fallbacks after the fact
|
|
@items = @query.results.includes(:translations).
|
|
paginate(page: params[:page], per_page: per_page)
|
|
assign_closeted!
|
|
respond_to do |format|
|
|
format.html {
|
|
@campaign = Campaign.current rescue nil
|
|
if @items.count == 1
|
|
redirect_to @items.first
|
|
else
|
|
render
|
|
end
|
|
}
|
|
format.json {
|
|
render json: {items: @items, total_pages: @items.total_pages,
|
|
query: @query.to_s}
|
|
}
|
|
format.js {
|
|
render json: {items: @items, total_pages: @items.total_pages,
|
|
query: @query.to_s},
|
|
callback: params[:callback]
|
|
}
|
|
end
|
|
end
|
|
elsif params.has_key?(:ids) && params[:ids].is_a?(Array)
|
|
@items = Item.find(params[:ids])
|
|
assign_closeted!
|
|
respond_to do |format|
|
|
format.json { render json: @items }
|
|
end
|
|
else
|
|
respond_to do |format|
|
|
format.html {
|
|
@campaign = Campaign.current rescue nil
|
|
@newest_items = Item.newest.includes(:translations).limit(18)
|
|
}
|
|
format.js { render json: {error: '$q required'}}
|
|
end
|
|
end
|
|
end
|
|
|
|
def show
|
|
@item = Item.find params[:id]
|
|
|
|
respond_to do |format|
|
|
format.html do
|
|
@trades = @item.closet_hangers.trading.includes(:user).user_is_active.
|
|
order('users.last_trade_activity_at DESC').to_trades
|
|
|
|
@contributors_with_counts = @item.contributors_with_counts
|
|
|
|
if user_signed_in?
|
|
# Empty arrays are important so that we can loop over this and still
|
|
# show the generic no-list case
|
|
@current_user_lists = {true => [], false => []}
|
|
current_user.closet_lists.alphabetical.each do |list|
|
|
@current_user_lists[list.hangers_owned] << list
|
|
end
|
|
|
|
@current_user_quantities = Hash.new(0) # default is zero
|
|
hangers = current_user.closet_hangers.where(item_id: @item.id).
|
|
select([:owned, :list_id, :quantity])
|
|
|
|
hangers.each do |hanger|
|
|
key = hanger.list_id || hanger.owned
|
|
@current_user_quantities[key] = hanger.quantity
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
format.gif do
|
|
expires_in 1.month
|
|
redirect_to @item.thumbnail_url
|
|
end
|
|
end
|
|
end
|
|
|
|
def needed
|
|
if params[:color] && params[:species]
|
|
@pet_type = PetType.find_by_color_id_and_species_id(
|
|
params[:color],
|
|
params[:species]
|
|
)
|
|
end
|
|
|
|
unless @pet_type
|
|
raise ActiveRecord::RecordNotFound, 'Pet type not found'
|
|
end
|
|
|
|
@items = @pet_type.needed_items.includes(:translations).
|
|
alphabetize_by_translations
|
|
assign_closeted!
|
|
|
|
respond_to do |format|
|
|
format.html { @pet_name = params[:name] ; render :layout => 'application' }
|
|
format.json { render :json => @items }
|
|
end
|
|
end
|
|
|
|
protected
|
|
|
|
def assign_closeted!
|
|
current_user.assign_closeted_to_items!(@items) if user_signed_in?
|
|
end
|
|
|
|
def search_error(e)
|
|
@items = []
|
|
respond_to do |format|
|
|
format.html { flash.now[:alert] = e.message; render }
|
|
format.json { render :json => {error: e.message} }
|
|
format.js { render :json => {error: e.message},
|
|
:callback => params[:callback] }
|
|
end
|
|
end
|
|
|
|
def set_query
|
|
q = params[:q]
|
|
if q.is_a?(String)
|
|
begin
|
|
@query = Item::Search::Query.from_text(q, current_user)
|
|
rescue
|
|
# Set the query string for error handling messages, but let the error
|
|
# bubble up.
|
|
@query = params[:q]
|
|
raise
|
|
end
|
|
elsif q.is_a?(Hash)
|
|
@query = Item::Search::Query.from_params(q, current_user)
|
|
end
|
|
end
|
|
end
|