From 7df38e129f197d4679021a70bdb0142ea9ed2de7 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Wed, 16 Nov 2016 19:19:14 +0100 Subject: [PATCH] Iteration G1. --- app/assets/javascripts/orders.coffee | 3 + app/assets/stylesheets/application.scss | 40 ++++++++++ app/assets/stylesheets/orders.scss | 3 + app/controllers/orders_controller.rb | 87 ++++++++++++++++++++++ app/helpers/orders_helper.rb | 2 + app/models/line_item.rb | 3 +- app/models/order.rb | 17 +++++ app/views/carts/_cart.html.erb | 1 + app/views/line_items/create.js.erb | 2 + app/views/orders/_form.html.erb | 37 +++++++++ app/views/orders/_order.json.jbuilder | 2 + app/views/orders/edit.html.erb | 6 ++ app/views/orders/index.html.erb | 33 ++++++++ app/views/orders/index.json.jbuilder | 1 + app/views/orders/new.html.erb | 6 ++ app/views/orders/show.html.erb | 24 ++++++ app/views/orders/show.json.jbuilder | 1 + config/routes.rb | 1 + db/migrate/20161116161401_create_orders.rb | 12 +++ .../20161116161423_add_order_to_line_item.rb | 5 ++ db/schema.rb | 13 +++- test/controllers/orders_controller_test.rb | 56 ++++++++++++++ test/fixtures/line_items.yml | 4 +- test/fixtures/orders.yml | 13 ++++ test/models/order_test.rb | 7 ++ 25 files changed, 375 insertions(+), 4 deletions(-) create mode 100644 app/assets/javascripts/orders.coffee create mode 100644 app/assets/stylesheets/orders.scss create mode 100644 app/controllers/orders_controller.rb create mode 100644 app/helpers/orders_helper.rb create mode 100644 app/models/order.rb create mode 100644 app/views/orders/_form.html.erb create mode 100644 app/views/orders/_order.json.jbuilder create mode 100644 app/views/orders/edit.html.erb create mode 100644 app/views/orders/index.html.erb create mode 100644 app/views/orders/index.json.jbuilder create mode 100644 app/views/orders/new.html.erb create mode 100644 app/views/orders/show.html.erb create mode 100644 app/views/orders/show.json.jbuilder create mode 100644 db/migrate/20161116161401_create_orders.rb create mode 100644 db/migrate/20161116161423_add_order_to_line_item.rb create mode 100644 test/controllers/orders_controller_test.rb create mode 100644 test/fixtures/orders.yml create mode 100644 test/models/order_test.rb diff --git a/app/assets/javascripts/orders.coffee b/app/assets/javascripts/orders.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/orders.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index f2773a6..dcb5b93 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -109,3 +109,43 @@ display: none; } } + + .depot_form { + fieldset { + background: #efe; + + legend { + color: #dfd; + background: #141; + font-family: sans-serif; + padding: 0.2em 1em; + } + + div { + margin-bottom: 0.3em; + } + } + + form { + label { + width: 5em; + float: left; + text-align: right; + padding-top: 0.2em; + margin-right: 0.1em; + display: block; + } + + select, textarea, input { + margin-left: 0.5em; + } + + .submit { + margin-left: 4em; + } + + br { + display: none + } + } +} diff --git a/app/assets/stylesheets/orders.scss b/app/assets/stylesheets/orders.scss new file mode 100644 index 0000000..7415069 --- /dev/null +++ b/app/assets/stylesheets/orders.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Orders controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb new file mode 100644 index 0000000..2feec9a --- /dev/null +++ b/app/controllers/orders_controller.rb @@ -0,0 +1,87 @@ +class OrdersController < ApplicationController + include CurrentCart + before_action :set_cart, only: [:new, :create] + before_action :ensure_cart_isnt_empty, only: :new + before_action :set_order, only: [:show, :edit, :update, :destroy] + + # GET /orders + # GET /orders.json + def index + @orders = Order.all + end + + # GET /orders/1 + # GET /orders/1.json + def show + end + + # GET /orders/new + def new + @order = Order.new + end + + # GET /orders/1/edit + def edit + end + + # POST /orders + # POST /orders.json + def create + @order = Order.new(order_params) + @order.add_line_items_from_cart(@cart) + + respond_to do |format| + if @order.save + Cart.destroy(session[:cart_id]) + session[:cart_id] = nil + + format.html { redirect_to store_index_url, notice: 'Thank you for your order.' } + format.json { render :show, status: :created, location: @order } + else + format.html { render :new } + format.json { render json: @order.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /orders/1 + # PATCH/PUT /orders/1.json + def update + respond_to do |format| + if @order.update(order_params) + format.html { redirect_to @order, notice: 'Order was successfully updated.' } + format.json { render :show, status: :ok, location: @order } + else + format.html { render :edit } + format.json { render json: @order.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /orders/1 + # DELETE /orders/1.json + def destroy + @order.destroy + respond_to do |format| + format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_order + @order = Order.find(params[:id]) + end + + # Never trust parameters from the scary internet, only allow the white list through. + def order_params + params.require(:order).permit(:name, :address, :email, :pay_type) + end + + def ensure_cart_isnt_empty + if @cart.line_items.empty? + redirect_to store_index_url, notice: 'Your cart is empty' + end + end +end diff --git a/app/helpers/orders_helper.rb b/app/helpers/orders_helper.rb new file mode 100644 index 0000000..443227f --- /dev/null +++ b/app/helpers/orders_helper.rb @@ -0,0 +1,2 @@ +module OrdersHelper +end diff --git a/app/models/line_item.rb b/app/models/line_item.rb index 2cdd111..62fe72f 100644 --- a/app/models/line_item.rb +++ b/app/models/line_item.rb @@ -1,5 +1,6 @@ class LineItem < ApplicationRecord - belongs_to :product + belongs_to :order, optional: true + belongs_to :product, optional: true belongs_to :cart def total_price diff --git a/app/models/order.rb b/app/models/order.rb new file mode 100644 index 0000000..fc09bd4 --- /dev/null +++ b/app/models/order.rb @@ -0,0 +1,17 @@ +class Order < ApplicationRecord + has_many :line_items, dependent: :destroy + enum pay_type: { + "Check" => 0, + "Credit card" => 1, + "Purchase order" => 2 + } + validates :name, :address, :email, :pay_type, presence: true + validates :pay_type, inclusion: pay_types.keys + + def add_line_items_from_cart(cart) + cart.line_items.each do |item| + item.cart_id = nil + line_items << item + end + end +end diff --git a/app/views/carts/_cart.html.erb b/app/views/carts/_cart.html.erb index ed3a0a2..c2263e9 100644 --- a/app/views/carts/_cart.html.erb +++ b/app/views/carts/_cart.html.erb @@ -10,4 +10,5 @@ +<%= button_to 'Checkout', new_order_path, method: :get %> <%= button_to 'Empty Cart', cart, method: :delete, data: { confirm: 'Are you sure?'} %> diff --git a/app/views/line_items/create.js.erb b/app/views/line_items/create.js.erb index 47d7f7e..fe0711f 100644 --- a/app/views/line_items/create.js.erb +++ b/app/views/line_items/create.js.erb @@ -1,3 +1,5 @@ +$('#notice').hide(); + if ($('#cart tr').length == 1) { $('#cart').show('blind', 1000); } $('#cart').html("<%=j render(@cart) %>") diff --git a/app/views/orders/_form.html.erb b/app/views/orders/_form.html.erb new file mode 100644 index 0000000..0462192 --- /dev/null +++ b/app/views/orders/_form.html.erb @@ -0,0 +1,37 @@ +<%= form_for(order) do |f| %> + <% if order.errors.any? %> +
+

<%= pluralize(order.errors.count, "error") %> prohibited this order from being saved:

+ + +
+ <% end %> + +
+ <%= f.label :name %> + <%= f.text_field :name, size: 40 %> +
+ +
+ <%= f.label :address %> + <%= f.text_area :address, rows: 3, cols: 40 %> +
+ +
+ <%= f.label :email %> + <%= f.email_field :email, size: 40 %> +
+ +
+ <%= f.label :pay_type %> + <%= f.select :pay_type, Order.pay_types.keys, prompt: 'Select a payment method' %> +
+ +
+ <%= f.submit 'Place order' %> +
+<% end %> diff --git a/app/views/orders/_order.json.jbuilder b/app/views/orders/_order.json.jbuilder new file mode 100644 index 0000000..69b12e5 --- /dev/null +++ b/app/views/orders/_order.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! order, :id, :name, :address, :email, :pay_type, :created_at, :updated_at +json.url order_url(order, format: :json) \ No newline at end of file diff --git a/app/views/orders/edit.html.erb b/app/views/orders/edit.html.erb new file mode 100644 index 0000000..e23883c --- /dev/null +++ b/app/views/orders/edit.html.erb @@ -0,0 +1,6 @@ +

Editing Order

+ +<%= render 'form', order: @order %> + +<%= link_to 'Show', @order %> | +<%= link_to 'Back', orders_path %> diff --git a/app/views/orders/index.html.erb b/app/views/orders/index.html.erb new file mode 100644 index 0000000..e203074 --- /dev/null +++ b/app/views/orders/index.html.erb @@ -0,0 +1,33 @@ +

<%= notice %>

+ +

Orders

+ + + + + + + + + + + + + + <% @orders.each do |order| %> + + + + + + + + + + <% end %> + +
NameAddressEmailPay type
<%= order.name %><%= order.address %><%= order.email %><%= order.pay_type %><%= link_to 'Show', order %><%= link_to 'Edit', edit_order_path(order) %><%= link_to 'Destroy', order, method: :delete, data: { confirm: 'Are you sure?' } %>
+ +
+ +<%= link_to 'New Order', new_order_path %> diff --git a/app/views/orders/index.json.jbuilder b/app/views/orders/index.json.jbuilder new file mode 100644 index 0000000..fa1101c --- /dev/null +++ b/app/views/orders/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @orders, partial: 'orders/order', as: :order \ No newline at end of file diff --git a/app/views/orders/new.html.erb b/app/views/orders/new.html.erb new file mode 100644 index 0000000..8ecf6b3 --- /dev/null +++ b/app/views/orders/new.html.erb @@ -0,0 +1,6 @@ +
+
+ Please Enter Your Details + <%= render 'form', order: @order %> +
+
diff --git a/app/views/orders/show.html.erb b/app/views/orders/show.html.erb new file mode 100644 index 0000000..38e31a6 --- /dev/null +++ b/app/views/orders/show.html.erb @@ -0,0 +1,24 @@ +

<%= notice %>

+ +

+ Name: + <%= @order.name %> +

+ +

+ Address: + <%= @order.address %> +

+ +

+ Email: + <%= @order.email %> +

+ +

+ Pay type: + <%= @order.pay_type %> +

+ +<%= link_to 'Edit', edit_order_path(@order) %> | +<%= link_to 'Back', orders_path %> diff --git a/app/views/orders/show.json.jbuilder b/app/views/orders/show.json.jbuilder new file mode 100644 index 0000000..04cffea --- /dev/null +++ b/app/views/orders/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "orders/order", order: @order \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 012abe1..2c68730 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :orders resources :line_items resources :carts root 'store#index', as: 'store_index' diff --git a/db/migrate/20161116161401_create_orders.rb b/db/migrate/20161116161401_create_orders.rb new file mode 100644 index 0000000..61d2b59 --- /dev/null +++ b/db/migrate/20161116161401_create_orders.rb @@ -0,0 +1,12 @@ +class CreateOrders < ActiveRecord::Migration[5.0] + def change + create_table :orders do |t| + t.string :name + t.text :address + t.string :email + t.integer :pay_type + + t.timestamps + end + end +end diff --git a/db/migrate/20161116161423_add_order_to_line_item.rb b/db/migrate/20161116161423_add_order_to_line_item.rb new file mode 100644 index 0000000..0299a87 --- /dev/null +++ b/db/migrate/20161116161423_add_order_to_line_item.rb @@ -0,0 +1,5 @@ +class AddOrderToLineItem < ActiveRecord::Migration[5.0] + def change + add_reference :line_items, :order, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 4cffb0a..85e47a6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161116091835) do +ActiveRecord::Schema.define(version: 20161116161423) do create_table "carts", force: :cascade do |t| t.datetime "created_at", null: false @@ -23,10 +23,21 @@ ActiveRecord::Schema.define(version: 20161116091835) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "quantity", default: 1 + t.integer "order_id" t.index ["cart_id"], name: "index_line_items_on_cart_id" + t.index ["order_id"], name: "index_line_items_on_order_id" t.index ["product_id"], name: "index_line_items_on_product_id" end + create_table "orders", force: :cascade do |t| + t.string "name" + t.text "address" + t.string "email" + t.integer "pay_type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "products", force: :cascade do |t| t.string "title" t.text "description" diff --git a/test/controllers/orders_controller_test.rb b/test/controllers/orders_controller_test.rb new file mode 100644 index 0000000..06d7b29 --- /dev/null +++ b/test/controllers/orders_controller_test.rb @@ -0,0 +1,56 @@ +require 'test_helper' + +class OrdersControllerTest < ActionDispatch::IntegrationTest + setup do + @order = orders(:one) + end + + test "should get index" do + get orders_url + assert_response :success + end + + test "requires item in cart" do + get new_order_url + assert_redirected_to store_index_url + assert_equal flash[:notice], 'Your cart is empty' + end + + test "should get new" do + post line_items_url, params: { product_id: products(:ruby).id } + + get new_order_url + assert_response :success + end + + test "should create order" do + assert_difference('Order.count') do + post orders_url, params: { order: { address: @order.address, email: @order.email, name: @order.name, pay_type: @order.pay_type } } + end + + assert_redirected_to store_index_url + end + + test "should show order" do + get order_url(@order) + assert_response :success + end + + test "should get edit" do + get edit_order_url(@order) + assert_response :success + end + + test "should update order" do + patch order_url(@order), params: { order: { address: @order.address, email: @order.email, name: @order.name, pay_type: @order.pay_type } } + assert_redirected_to order_url(@order) + end + + test "should destroy order" do + assert_difference('Order.count', -1) do + delete order_url(@order) + end + + assert_redirected_to orders_url + end +end diff --git a/test/fixtures/line_items.yml b/test/fixtures/line_items.yml index 4db5df2..f9a992f 100644 --- a/test/fixtures/line_items.yml +++ b/test/fixtures/line_items.yml @@ -6,5 +6,5 @@ one: cart: one two: - product: two - cart: two + product: ruby + order: one diff --git a/test/fixtures/orders.yml b/test/fixtures/orders.yml new file mode 100644 index 0000000..4eb2e24 --- /dev/null +++ b/test/fixtures/orders.yml @@ -0,0 +1,13 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: Dave Thomas + address: MyText + email: dave@example.org + pay_type: Check + +two: + name: MyString + address: MyText + email: MyString + pay_type: 1 diff --git a/test/models/order_test.rb b/test/models/order_test.rb new file mode 100644 index 0000000..15b8ed1 --- /dev/null +++ b/test/models/order_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class OrderTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end