From f4a463b2d77fccc4919aea19a54736db6e485688 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Thu, 22 Nov 2007 11:13:49 -0800 Subject: [PATCH] Add merchandise MVC This adds a MVC which handles all non-rentable merchandise, such as popcorn, posters, etc. Signed-off-by: Ira W. Snyder --- app/controllers/merchandise_controller.rb | 51 ++++++++++ app/helpers/merchandise_helper.rb | 2 + app/models/merchandise.rb | 12 +++ app/views/layouts/merchandise.rhtml | 17 ++++ app/views/merchandise/_form.rhtml | 13 +++ app/views/merchandise/edit.rhtml | 9 ++ app/views/merchandise/list.rhtml | 27 +++++ app/views/merchandise/new.rhtml | 8 ++ app/views/merchandise/show.rhtml | 8 ++ db/development.sqlite3 | Bin 9216 -> 10240 bytes db/migrate/014_create_merchandises.rb | 13 +++ db/schema.rb | 8 +- test/fixtures/merchandises.yml | 5 + .../functional/merchandise_controller_test.rb | 92 ++++++++++++++++++ test/unit/merchandise_test.rb | 10 ++ 15 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 app/controllers/merchandise_controller.rb create mode 100644 app/helpers/merchandise_helper.rb create mode 100644 app/models/merchandise.rb create mode 100644 app/views/layouts/merchandise.rhtml create mode 100644 app/views/merchandise/_form.rhtml create mode 100644 app/views/merchandise/edit.rhtml create mode 100644 app/views/merchandise/list.rhtml create mode 100644 app/views/merchandise/new.rhtml create mode 100644 app/views/merchandise/show.rhtml create mode 100644 db/migrate/014_create_merchandises.rb create mode 100644 test/fixtures/merchandises.yml create mode 100644 test/functional/merchandise_controller_test.rb create mode 100644 test/unit/merchandise_test.rb diff --git a/app/controllers/merchandise_controller.rb b/app/controllers/merchandise_controller.rb new file mode 100644 index 0000000..062a3ef --- /dev/null +++ b/app/controllers/merchandise_controller.rb @@ -0,0 +1,51 @@ +class MerchandiseController < ApplicationController + def index + list + render :action => 'list' + end + + # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) + verify :method => :post, :only => [ :destroy, :create, :update ], + :redirect_to => { :action => :list } + + def list + @merchandise_pages, @merchandises = paginate :merchandises, :per_page => 10 + end + + def show + @merchandise = Merchandise.find(params[:id]) + end + + def new + @merchandise = Merchandise.new + end + + def create + @merchandise = Merchandise.new(params[:merchandise]) + if @merchandise.save + flash[:notice] = 'Merchandise was successfully created.' + redirect_to :action => 'list' + else + render :action => 'new' + end + end + + def edit + @merchandise = Merchandise.find(params[:id]) + end + + def update + @merchandise = Merchandise.find(params[:id]) + if @merchandise.update_attributes(params[:merchandise]) + flash[:notice] = 'Merchandise was successfully updated.' + redirect_to :action => 'show', :id => @merchandise + else + render :action => 'edit' + end + end + + def destroy + Merchandise.find(params[:id]).destroy + redirect_to :action => 'list' + end +end diff --git a/app/helpers/merchandise_helper.rb b/app/helpers/merchandise_helper.rb new file mode 100644 index 0000000..e6bfee2 --- /dev/null +++ b/app/helpers/merchandise_helper.rb @@ -0,0 +1,2 @@ +module MerchandiseHelper +end diff --git a/app/models/merchandise.rb b/app/models/merchandise.rb new file mode 100644 index 0000000..463cfd3 --- /dev/null +++ b/app/models/merchandise.rb @@ -0,0 +1,12 @@ +class Merchandise < ActiveRecord::Base + validates_presence_of :name + validates_numericality_of :quantity + validates_numericality_of :price + + protected + def validate + errors.add(:quantity, "cannot be negative") if quantity < 0 + errors.add(:price, "cannot be negative") if price < 0 + errors.add(:price, "cannot be less than $0.01") if price < 0.01 + end +end diff --git a/app/views/layouts/merchandise.rhtml b/app/views/layouts/merchandise.rhtml new file mode 100644 index 0000000..e6a6a3f --- /dev/null +++ b/app/views/layouts/merchandise.rhtml @@ -0,0 +1,17 @@ + + + + + + Merchandise: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +<%= yield %> + + + diff --git a/app/views/merchandise/_form.rhtml b/app/views/merchandise/_form.rhtml new file mode 100644 index 0000000..d7f7735 --- /dev/null +++ b/app/views/merchandise/_form.rhtml @@ -0,0 +1,13 @@ +<%= error_messages_for 'merchandise' %> + + +


+<%= text_field 'merchandise', 'name' %>

+ +


+<%= text_field 'merchandise', 'quantity' %>

+ +


+<%= text_field 'merchandise', 'price' %>

+ + diff --git a/app/views/merchandise/edit.rhtml b/app/views/merchandise/edit.rhtml new file mode 100644 index 0000000..7efb9d0 --- /dev/null +++ b/app/views/merchandise/edit.rhtml @@ -0,0 +1,9 @@ +

Editing merchandise

+ +<% form_tag :action => 'update', :id => @merchandise do %> + <%= render :partial => 'form' %> + <%= submit_tag 'Edit' %> +<% end %> + +<%= link_to 'Show', :action => 'show', :id => @merchandise %> | +<%= link_to 'Back', :action => 'list' %> diff --git a/app/views/merchandise/list.rhtml b/app/views/merchandise/list.rhtml new file mode 100644 index 0000000..c8a1ba0 --- /dev/null +++ b/app/views/merchandise/list.rhtml @@ -0,0 +1,27 @@ +

Listing merchandises

+ + + + <% for column in Merchandise.content_columns %> + + <% end %> + + +<% for merchandise in @merchandises %> + + <% for column in Merchandise.content_columns %> + + <% end %> + + + + +<% end %> +
<%= column.human_name %>
<%=h merchandise.send(column.name) %><%= link_to 'Show', :action => 'show', :id => merchandise %><%= link_to 'Edit', :action => 'edit', :id => merchandise %><%= link_to 'Destroy', { :action => 'destroy', :id => merchandise }, :confirm => 'Are you sure?', :method => :post %>
+ +<%= link_to 'Previous page', { :page => @merchandise_pages.current.previous } if @merchandise_pages.current.previous %> +<%= link_to 'Next page', { :page => @merchandise_pages.current.next } if @merchandise_pages.current.next %> + +
+ +<%= link_to 'New merchandise', :action => 'new' %> diff --git a/app/views/merchandise/new.rhtml b/app/views/merchandise/new.rhtml new file mode 100644 index 0000000..f03a8fa --- /dev/null +++ b/app/views/merchandise/new.rhtml @@ -0,0 +1,8 @@ +

New merchandise

+ +<% form_tag :action => 'create' do %> + <%= render :partial => 'form' %> + <%= submit_tag "Create" %> +<% end %> + +<%= link_to 'Back', :action => 'list' %> diff --git a/app/views/merchandise/show.rhtml b/app/views/merchandise/show.rhtml new file mode 100644 index 0000000..9c90624 --- /dev/null +++ b/app/views/merchandise/show.rhtml @@ -0,0 +1,8 @@ +<% for column in Merchandise.content_columns %> +

+ <%= column.human_name %>: <%=h @merchandise.send(column.name) %> +

+<% end %> + +<%= link_to 'Edit', :action => 'edit', :id => @merchandise %> | +<%= link_to 'Back', :action => 'list' %> diff --git a/db/development.sqlite3 b/db/development.sqlite3 index ce0b240afc515137a5ba9e0340b4d186f9d6503b..7b507a52503d1cf5d81c2f515c3a32ffd2090749 100644 GIT binary patch delta 267 zcmZqhXb6}fEqIjy6&P>Sxy;VUw~2#Af`^6S1_P52(?rHa3^yh=o^WV%=VTXGRb^}n zEJ;ktNzF|yO3p~kOUW!wEkbDj>;BKCkHHp`)NwSelqul37xz zq>!0clA4}cq~PM}<{0V|qF|ul=O3cr7wY2!R8~-wnVhPmkdm65nVXoSVWDHBiBPDy zd68lq6Av%Y^-RoX8JJ%&pWQ6Ta*)|rnu(P`osr!qu_!%NAt1jXIlm~6%Rz-zZb#tj SRuM*!Bx5kpyd0QhH4^}DBur-j delta 67 zcmZn&Xz-XIEqIXu6&P*Qxy;VUyNQEEf{U4P5d)JD(?rHa8yh false + t.column :quantity, :integer, :null => false, :default => 0 + t.column :price, :decimal, :precision => 8, :scale =>2, :default => 0 + end + end + + def self.down + drop_table :merchandises + end +end diff --git a/db/schema.rb b/db/schema.rb index 77281f8..73ad8b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,7 +2,7 @@ # migrations feature of ActiveRecord to incrementally modify your database, and # then regenerate this schema definition. -ActiveRecord::Schema.define(:version => 13) do +ActiveRecord::Schema.define(:version => 14) do create_table "coitems", :force => true do |t| t.column "customer_id", :integer @@ -23,6 +23,12 @@ ActiveRecord::Schema.define(:version => 13) do t.column "name", :string, :null => false end + create_table "merchandises", :force => true do |t| + t.column "name", :string, :null => false + t.column "quantity", :integer, :default => 0, :null => false + t.column "price", :decimal, :precision => 8, :scale => 2, :default => 0.0 + end + create_table "rentables", :force => true do |t| t.column "type", :string t.column "title", :string diff --git a/test/fixtures/merchandises.yml b/test/fixtures/merchandises.yml new file mode 100644 index 0000000..b49c4eb --- /dev/null +++ b/test/fixtures/merchandises.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +one: + id: 1 +two: + id: 2 diff --git a/test/functional/merchandise_controller_test.rb b/test/functional/merchandise_controller_test.rb new file mode 100644 index 0000000..0d58049 --- /dev/null +++ b/test/functional/merchandise_controller_test.rb @@ -0,0 +1,92 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'merchandise_controller' + +# Re-raise errors caught by the controller. +class MerchandiseController; def rescue_action(e) raise e end; end + +class MerchandiseControllerTest < Test::Unit::TestCase + fixtures :merchandises + + def setup + @controller = MerchandiseController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + + @first_id = merchandises(:first).id + end + + def test_index + get :index + assert_response :success + assert_template 'list' + end + + def test_list + get :list + + assert_response :success + assert_template 'list' + + assert_not_nil assigns(:merchandises) + end + + def test_show + get :show, :id => @first_id + + assert_response :success + assert_template 'show' + + assert_not_nil assigns(:merchandise) + assert assigns(:merchandise).valid? + end + + def test_new + get :new + + assert_response :success + assert_template 'new' + + assert_not_nil assigns(:merchandise) + end + + def test_create + num_merchandises = Merchandise.count + + post :create, :merchandise => {} + + assert_response :redirect + assert_redirected_to :action => 'list' + + assert_equal num_merchandises + 1, Merchandise.count + end + + def test_edit + get :edit, :id => @first_id + + assert_response :success + assert_template 'edit' + + assert_not_nil assigns(:merchandise) + assert assigns(:merchandise).valid? + end + + def test_update + post :update, :id => @first_id + assert_response :redirect + assert_redirected_to :action => 'show', :id => @first_id + end + + def test_destroy + assert_nothing_raised { + Merchandise.find(@first_id) + } + + post :destroy, :id => @first_id + assert_response :redirect + assert_redirected_to :action => 'list' + + assert_raise(ActiveRecord::RecordNotFound) { + Merchandise.find(@first_id) + } + end +end diff --git a/test/unit/merchandise_test.rb b/test/unit/merchandise_test.rb new file mode 100644 index 0000000..efba16f --- /dev/null +++ b/test/unit/merchandise_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class MerchandiseTest < Test::Unit::TestCase + fixtures :merchandises + + # Replace this with your real tests. + def test_truth + assert true + end +end -- 2.25.1