From 951fe14acc706a4c5ec043e20b3cbfee2b9754d6 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sat, 7 Mar 2009 00:20:39 +0000 Subject: [PATCH] End chapter 10 --- app/controllers/store_controller.rb | 26 ++++++++++++++ app/models/line_item.rb | 10 ++++++ app/models/order.rb | 18 ++++++++++ app/views/layouts/line_items.html.erb | 17 ++++++++++ app/views/layouts/orders.html.erb | 17 ++++++++++ app/views/layouts/store.html.erb | 2 +- app/views/store/_cart.html.erb | 4 +++ app/views/store/_checkout.html.erb | 29 ++++++++++++++++ app/views/store/add_to_cart.js.rjs | 3 ++ app/views/store/checkout.html.erb | 1 + app/views/store/checkout.js.rjs | 1 + app/views/store/index.html.erb | 2 ++ db/migrate/20090304153209_create_orders.rb | 2 +- .../20090304153613_create_line_items.rb | 15 +++++--- db/schema.rb | 23 ++++++++++++- public/stylesheets/depot.css | 34 +++++++++++++++++++ 16 files changed, 197 insertions(+), 7 deletions(-) create mode 100644 app/views/layouts/line_items.html.erb create mode 100644 app/views/layouts/orders.html.erb create mode 100644 app/views/store/_checkout.html.erb create mode 100644 app/views/store/checkout.html.erb create mode 100644 app/views/store/checkout.js.rjs diff --git a/app/controllers/store_controller.rb b/app/controllers/store_controller.rb index 3b2e6b8..de9e160 100644 --- a/app/controllers/store_controller.rb +++ b/app/controllers/store_controller.rb @@ -21,7 +21,33 @@ class StoreController < ApplicationController session[:cart] = nil redirect_to_index unless request.xhr? end + + def checkout + @cart = find_cart + if @cart.items.empty? + redirect_to_index("Your cart is empty" ) + else + @order = Order.new + respond_to do |format| + format.js if request.xhr? + format.html + end + end + end + + def save_order + @cart = find_cart + @order = Order.new(params[:order]) + @order.add_line_items_from_cart(@cart) + if @order.save + session[:cart] = nil + redirect_to_index("Thank you for your order") + else + render :action => 'checkout' + end + end + private def find_cart diff --git a/app/models/line_item.rb b/app/models/line_item.rb index 988324c..61161a0 100644 --- a/app/models/line_item.rb +++ b/app/models/line_item.rb @@ -1,2 +1,12 @@ class LineItem < ActiveRecord::Base + belongs_to :order + belongs_to :product + + def self.from_cart_item(cart_item) + li = self.new + li.product = cart_item.product + li.quantity = cart_item.quantity + li.total_price = cart_item.price + li + end end diff --git a/app/models/order.rb b/app/models/order.rb index 0bcb158..bea4da6 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -1,2 +1,20 @@ class Order < ActiveRecord::Base + has_many :line_items + + PAYMENT_TYPES = [ + ["Cheque", "cheque"], + ["Credit card", "cc"], + ["Purchase order", "po"] + ] + + validates_presence_of :name, :address, :email, :pay_type + validates_inclusion_of :pay_type, :in => + PAYMENT_TYPES.map {|disp, value| value} + + def add_line_items_from_cart(cart) + cart.items.each do |item| + li = LineItem.from_cart_item(item) + line_items << li + end + end end diff --git a/app/views/layouts/line_items.html.erb b/app/views/layouts/line_items.html.erb new file mode 100644 index 0000000..78d24cc --- /dev/null +++ b/app/views/layouts/line_items.html.erb @@ -0,0 +1,17 @@ + + + + + + LineItems: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +<%= yield %> + + + diff --git a/app/views/layouts/orders.html.erb b/app/views/layouts/orders.html.erb new file mode 100644 index 0000000..ee970df --- /dev/null +++ b/app/views/layouts/orders.html.erb @@ -0,0 +1,17 @@ + + + + + + Orders: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +<%= yield %> + + + diff --git a/app/views/layouts/store.html.erb b/app/views/layouts/store.html.erb index e55726c..63c7dd9 100644 --- a/app/views/layouts/store.html.erb +++ b/app/views/layouts/store.html.erb @@ -17,7 +17,7 @@ <% hidden_div_if(@cart.items.empty?, :id => "cart") do %> <%= render(:partial => "cart" , :object => @cart) %> <% end %> - Home
+ Home
Questions
News
Contact
diff --git a/app/views/store/_cart.html.erb b/app/views/store/_cart.html.erb index cc84043..43e9a16 100644 --- a/app/views/store/_cart.html.erb +++ b/app/views/store/_cart.html.erb @@ -8,6 +8,10 @@ +<% form_remote_tag :url => {:action => 'checkout'} do %> + <%= submit_tag "Checkout" %> +<% end %> + <% form_remote_tag :url => {:action => 'empty_cart'} do %> <%= submit_tag "Empty cart" %> <% end %> diff --git a/app/views/store/_checkout.html.erb b/app/views/store/_checkout.html.erb new file mode 100644 index 0000000..f5cd24f --- /dev/null +++ b/app/views/store/_checkout.html.erb @@ -0,0 +1,29 @@ +
+ <%= error_messages_for 'order' %> + <% form_for :order, :url => { :action => :save_order } do |form| %> +
+ Please Enter Your Details +
+ <%= form.label :name, "Name:" %> + <%= form.text_field :name, :size => 40 %> +
+
+ <%= form.label :address, "Address:" %> + <%= form.text_area :address, :rows => 3, :cols => 40 %> +
+
+ <%= form.label :email, "E-Mail:" %> + <%= form.text_field :email, :size => 40 %> +
+
+ <%= form.label :pay_type, "Pay by:" %> + <%= + form.select :pay_type, + Order::PAYMENT_TYPES, + :prompt => "Select a payment method" + %> +
+ <%= submit_tag "Place Order" , :class => "submit" %> +
+ <% end %> +
\ No newline at end of file diff --git a/app/views/store/add_to_cart.js.rjs b/app/views/store/add_to_cart.js.rjs index 2ef0a83..25dc8ca 100644 --- a/app/views/store/add_to_cart.js.rjs +++ b/app/views/store/add_to_cart.js.rjs @@ -1,3 +1,5 @@ +page.select("div#notice").each {|div| div.hide} + page.replace_html("cart", :partial => 'cart', :object => @cart) page[:cart].visual_effect :blind_down if @cart.total_items == 1 @@ -5,3 +7,4 @@ page[:cart].visual_effect :blind_down if @cart.total_items == 1 page[:current_item].visual_effect :highlight, :startcolor => "#88ff88" , :endcolor => "#114411" + diff --git a/app/views/store/checkout.html.erb b/app/views/store/checkout.html.erb new file mode 100644 index 0000000..e41398d --- /dev/null +++ b/app/views/store/checkout.html.erb @@ -0,0 +1 @@ +<%= render(:partial => "checkout", :object => @order) %> diff --git a/app/views/store/checkout.js.rjs b/app/views/store/checkout.js.rjs new file mode 100644 index 0000000..d819e16 --- /dev/null +++ b/app/views/store/checkout.js.rjs @@ -0,0 +1 @@ +page.replace_html("main_panel", :partial => "checkout", :object => @order) diff --git a/app/views/store/index.html.erb b/app/views/store/index.html.erb index f3e7ebe..63c12da 100644 --- a/app/views/store/index.html.erb +++ b/app/views/store/index.html.erb @@ -1,3 +1,4 @@ +

Neil's Whimsical Store Catalogue

<% for product in @products -%> @@ -15,3 +16,4 @@
<% end %> + diff --git a/db/migrate/20090304153209_create_orders.rb b/db/migrate/20090304153209_create_orders.rb index a0a1598..3852118 100644 --- a/db/migrate/20090304153209_create_orders.rb +++ b/db/migrate/20090304153209_create_orders.rb @@ -4,7 +4,7 @@ class CreateOrders < ActiveRecord::Migration t.string :name t.text :address t.string :email - t.string :pay_type + t.string :pay_type, :limit => 10 t.timestamps end diff --git a/db/migrate/20090304153613_create_line_items.rb b/db/migrate/20090304153613_create_line_items.rb index 6870a05..fcd4625 100644 --- a/db/migrate/20090304153613_create_line_items.rb +++ b/db/migrate/20090304153613_create_line_items.rb @@ -1,13 +1,20 @@ class CreateLineItems < ActiveRecord::Migration def self.up create_table :line_items do |t| - t.integer :product_id - t.integer :order_id - t.integer :quantity - t.decimal :total_price + t.integer :product_id, :null => false + t.integer :order_id, :null => false + t.integer :quantity, :null => false + t.decimal :total_price, :null => false, :precision => 8, :scale => 2 t.timestamps end + + execute "alter table line_items add constraint fk_line_item_products + foreign key (product_id) references products(id)" + + execute "alter table line_items add constraint fk_line_item_orders + foreign key (order_id) references orders(id)" + end def self.down diff --git a/db/schema.rb b/db/schema.rb index d08e763..d017a09 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,28 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20090226212307) do +ActiveRecord::Schema.define(:version => 20090304153613) do + + create_table "line_items", :force => true do |t| + t.integer "product_id", :null => false + t.integer "order_id", :null => false + t.integer "quantity", :null => false + t.decimal "total_price", :precision => 8, :scale => 2, :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "line_items", ["order_id"], :name => "fk_line_item_orders" + add_index "line_items", ["product_id"], :name => "fk_line_item_products" + + create_table "orders", :force => true do |t| + t.string "name" + t.text "address" + t.string "email" + t.string "pay_type", :limit => 10 + t.datetime "created_at" + t.datetime "updated_at" + end create_table "products", :force => true do |t| t.string "title" diff --git a/public/stylesheets/depot.css b/public/stylesheets/depot.css index bb4934d..5579185 100644 --- a/public/stylesheets/depot.css +++ b/public/stylesheets/depot.css @@ -199,7 +199,41 @@ h1 { } /* END:cartside */ +/* START:form */ +/* Styles for order form */ +.depot-form fieldset { + background: #efe; +} + +.depot-form legend { + color: #dfd; + background: #141; + font-family: sans-serif; + padding: 0.2em 1em; +} + +.depot-form label { + width: 5em; + float: left; + text-align: right; + padding-top: 0.2em; + margin-right: 0.1em; + display: block; +} + +.depot-form select, .depot-form textarea, .depot-form input { + margin-left: 0.5em; +} + +.depot-form .submit { + margin-left: 4em; +} + +.depot-form div { + margin: 0.5em 0; +} +/* END:form */ /* The error box */ -- 2.34.1