impress/app/controllers/closet_hangers_controller.rb
Matchu 2df0133cff Oops, using item proxies broke closet comparison. Fix.
Turns out we need to assign closeted to actual items, not
the item proxies, since that's what we check against. (I
would've thought they're backed by the same instance of
the item anyway, but, whatever. The fix works :P)
2014-02-04 16:29:59 -06:00

229 lines
7.3 KiB
Ruby

class ClosetHangersController < ApplicationController
before_filter :authorize_user!, :only => [:destroy, :create, :update, :update_quantities, :petpage]
before_filter :find_item, :only => [:create, :update_quantities]
before_filter :find_user, :only => [:index, :petpage, :update_quantities]
def destroy
@closet_hanger = current_user.closet_hangers.find params[:id]
@closet_hanger.destroy
@item = @closet_hanger.item
closet_hanger_destroyed
end
def index
@public_perspective = params.has_key?(:public) || !user_is?(@user)
@perspective_user = current_user unless @public_perspective
closet_lists = @user.closet_lists
unless @perspective_user == @user
# If we run this when the user matches, we'll end up with effectively:
# WHERE belongs_to_user AND (is_public OR belongs_to_user)
# and it's a bit silly to put the SQL server through a condition that's
# always true.
closet_lists = closet_lists.visible_to(@perspective_user)
end
@closet_lists_by_owned = find_closet_lists_by_owned(closet_lists)
visible_groups = @user.closet_hangers_groups_visible_to(@perspective_user)
@unlisted_closet_hangers_by_owned = find_unlisted_closet_hangers_by_owned(visible_groups)
item_proxies = Item::ProxyArray.new
items = []
@closet_lists_by_owned.each do |owned, lists|
lists.each do |list|
list.hangers.each do |hanger|
hanger.item_proxy = Item::Proxy.new(hanger.item)
item_proxies << hanger.item_proxy
items << hanger.item
end
end
end
@unlisted_closet_hangers_by_owned.each do |owned, hangers|
hangers.each do |hanger|
hanger.item_proxy = Item::Proxy.new(hanger.item)
item_proxies << hanger.item_proxy
items << hanger.item
end
end
item_proxies.prepare_partial(:item_link_partial)
if @public_perspective && user_signed_in?
current_user.assign_closeted_to_items!(items)
end
end
def petpage
# Find all closet lists, and also the hangers of the visible closet lists
closet_lists = @user.closet_lists.select([:id, :name, :hangers_owned]).alphabetical
if params[:filter]
# If user specified which lists should be visible, restrict to those
if params[:lists] && params[:lists].respond_to?(:keys)
visible_closet_lists = closet_lists.where(:id => params[:lists].keys)
else
visible_closet_lists = []
end
else
# Otherwise, default to public lists
visible_closet_lists = closet_lists.public
end
@closet_lists_by_owned = closet_lists.group_by(&:hangers_owned)
@visible_closet_lists_by_owned = find_closet_lists_by_owned(visible_closet_lists)
# Find which groups (own/want) should be visible
if params[:filter]
# If user specified which groups should be visible, restrict to those
# (must be either true or false)
@visible_groups = []
if params[:groups] && params[:groups].respond_to?(:keys)
@visible_groups << true if params[:groups].keys.include?('true')
@visible_groups << false if params[:groups].keys.include?('false')
end
else
# Otherwise, default to public groups
@visible_groups = @user.public_closet_hangers_groups
end
@visible_unlisted_closet_hangers_by_owned =
find_unlisted_closet_hangers_by_owned(@visible_groups)
end
def create
@closet_hanger = current_user.closet_hangers.build(params[:closet_hanger])
@closet_hanger.item = @item
if @closet_hanger.save
closet_hanger_saved
else
closet_hanger_invalid
end
end
def update
@closet_hanger = current_user.closet_hangers.find(params[:id])
@closet_hanger.attributes = params[:closet_hanger]
@item = @closet_hanger.item
unless @closet_hanger.quantity == 0 # save the hanger, new record or not
if @closet_hanger.save
closet_hanger_saved
else
closet_hanger_invalid
end
else # delete the hanger since the user doesn't want it
@closet_hanger.destroy
closet_hanger_destroyed
end
end
def update_quantities
begin
ClosetHanger.transaction do
params[:quantity].each do |key, quantity|
ClosetHanger.set_quantity!(quantity, :user_id => @user.id,
:item_id => @item.id, :key => key)
end
flash[:success] = t('closet_hangers.update_quantities.success',
:item_name => @item.name)
end
rescue ActiveRecord::RecordInvalid => e
flash[:alert] = t('closet_hangers.update_quantities.invalid',
:errors => e.message)
end
redirect_to @item
end
private
def closet_hanger_destroyed
respond_to do |format|
format.html {
ownership_key = @closet_hanger.owned? ? 'owned' : 'wanted'
flash[:success] = t("closet_hangers.destroy.success.#{ownership_key}",
:item_name => @item.name)
redirect_back!(@item)
}
format.json { render :json => true }
end
end
def closet_hanger_invalid
respond_to do |format|
format.html {
ownership_key = @closet_hanger.owned? ? 'owned' : 'wanted'
flash[:alert] = t("closet_hangers.create.invalid.#{ownership_key}",
:item_name => @item.name,
:errors => @closet_hanger.errors.full_messages.to_sentence)
redirect_back!(@item)
}
format.json { render :json => {:errors => @closet_hanger.errors.full_messages}, :status => :unprocessable_entity }
end
end
def closet_hanger_saved
respond_to do |format|
format.html {
ownership_key = @closet_hanger.owned? ? 'owned' : 'wanted'
if @closet_hanger.list
flash[:success] = t("closet_hangers.create.success.#{ownership_key}.in_list",
:item_name => @item.name,
:list_name => @closet_hanger.list.name,
:count => @closet_hanger.quantity)
else
flash[:success] = t("closet_hangers.create.success.#{ownership_key}.unlisted",
:item_name => @item.name,
:count => @closet_hanger.quantity)
end
redirect_back!(@item)
}
format.json { render :json => true }
end
end
def find_item
@item = Item.find params[:item_id]
end
def find_user
if params[:user_id]
@user = User.find params[:user_id]
elsif user_signed_in?
redirect_to user_closet_hangers_path(current_user)
else
redirect_to login_path(:return_to => request.fullpath)
end
end
def find_closet_lists_by_owned(closet_lists)
return {} if closet_lists == []
closet_lists.alphabetical.includes(:hangers => {:item => :translations}).
group_by(&:hangers_owned)
end
def find_unlisted_closet_hangers_by_owned(visible_groups)
unless visible_groups.empty?
@user.closet_hangers.unlisted.
owned_before_wanted.alphabetical_by_item_name.
includes(:item => :translations).
where(:owned => [visible_groups]).
group_by(&:owned)
else
{}
end
end
def owned
owned = true
if params[:closet_hanger]
owned = case params[:closet_hanger][:owned]
when 'true', '1' then true
when 'false', '0' then false
end
end
end
end