diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4543f7c7..6c9a3e5e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,5 +10,13 @@ class ApplicationController < ActionController::Base def can_use_image_mode? user_signed_in? && current_user.image_mode_tester? end + + class AccessDenied < StandardError;end + + rescue_from AccessDenied, :with => :on_access_denied + + def on_access_denied + render :file => 'public/403.html', :layout => false, :status => :forbidden + end end diff --git a/app/controllers/closet_hangers_controller.rb b/app/controllers/closet_hangers_controller.rb index cc9e1a76..eb059dda 100644 --- a/app/controllers/closet_hangers_controller.rb +++ b/app/controllers/closet_hangers_controller.rb @@ -1,50 +1,45 @@ class ClosetHangersController < ApplicationController - before_filter :find_item, :only => [:create, :update] - - def create - @closet_hanger = new_hanger - save_hanger! - end - - def update - begin - @closet_hanger = @item.closet_hangers.find(params[:id]) - @closet_hanger.attributes = params[:closet_hanger] - rescue ActiveRecord::RecordNotFound - # Since updating a hanger is really just changing an item quantity, if - # for some reason this hanger doesn't exist (like if user left a tab - # open), we can still create a new hanger and do the job the user wants - @closet_hanger = new_hanger - end - save_hanger! - end + before_filter :authorize_user!, :only => [:set_quantity] def index @user = User.find params[:user_id] @closet_hangers = @user.closet_hangers.alphabetical_by_item_name.includes(:item) end - protected - - def find_item + # Since the user does not care about the idea of a hanger, but rather the + # quantity of an item they own, the user would expect a create form to work + # even after the record already exists, and an update form to work even after + # the record is deleted. So, create and update are aliased, and both find + # the record if it exists or create a new one if it does not. + # + # This is kinda a violation of REST. It's not worth breaking user + # expectations, though, and I can't really think of a genuinely RESTful way + # to pull this off. + def update @item = Item.find params[:item_id] - end + @closet_hanger = current_user.closet_hangers.find_or_initialize_by_item_id(@item.id) + @closet_hanger.attributes = params[:closet_hanger] - def new_hanger - current_user.closet_hangers.find_or_initialize_by_item_id(@item.id, params[:closet_hanger]) - end - - def save_hanger! - if @closet_hanger.quantity == 0 + unless @closet_hanger.quantity == 0 # save the hanger, new record or not + if @closet_hanger.save + flash[:success] = "Success! You own #{@closet_hanger.quantity} #{@item.name.pluralize}." + else + flash[:alert] = "We couldn't save how many of this item you own: #{@closet_hanger.errors.full_messages.to_sentence}" + end + else # delete the hanger since the user doesn't want it @closet_hanger.destroy flash[:success] = "Success! You do not own #{@item.name}." - elsif @closet_hanger.save - flash[:success] = "Success! You own #{@closet_hanger.quantity} #{@item.name.pluralize}." - else - flash[:alert] = "We couldn't save how many of this item you own: #{@closet_hanger.errors.full_messages.to_sentence}" end redirect_to @item end + + alias_method :create, :update + + protected + + def authorize_user! + raise AccessDenied unless user_signed_in? && current_user.id == params[:user_id].to_i + end end diff --git a/app/views/items/show.html.haml b/app/views/items/show.html.haml index a9589995..81c99120 100644 --- a/app/views/items/show.html.haml +++ b/app/views/items/show.html.haml @@ -13,7 +13,7 @@ = link_to 'NeoItems', neoitems_url_for(@item), :class => 'button' - if @hanger - = form_for([@item, @hanger], :html => {:id => 'closet-hanger-form'}) do |f| + = form_for(@hanger, :url => user_item_closet_hanger_path(current_user, @item), :html => {:id => 'closet-hanger-form'}) do |f| = f.label :quantity, "How many of these do you own?" = f.number_field :quantity, :min => 0, :required => true = f.submit "Save" diff --git a/config/routes.rb b/config/routes.rb index 9189fe2a..6dbb1921 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,8 +19,6 @@ OpenneoImpressItems::Application.routes.draw do |map| collection do get :needed end - - resources :closet_hangers, :only => [:create, :update] end resources :outfits, :only => [:show, :create, :update, :destroy] resources :pet_attributes, :only => [:index] @@ -40,6 +38,10 @@ OpenneoImpressItems::Application.routes.draw do |map| resources :user, :only => [] do resources :contributions, :only => [:index] resources :closet_hangers, :only => [:index], :path => 'closet' + + resources :items, :only => [] do + resource :closet_hanger, :only => [:create, :update] + end end match 'users/top-contributors' => 'users#top_contributors', :as => :top_contributors diff --git a/public/403.html b/public/403.html new file mode 100644 index 00000000..0ccf5383 --- /dev/null +++ b/public/403.html @@ -0,0 +1,28 @@ + + +
+This resource might belong to another user, or your session may have expired.
+ +