Commit b07e1f6f by Tran Hoang Viet

Merge branch 'vietth_feat_product_management' into 'develop'

Vietth feature product management

See merge request !3
parents 7721b77f d570482e
...@@ -11,3 +11,4 @@ ...@@ -11,3 +11,4 @@
/log/* /log/*
!/log/.keep !/log/.keep
/tmp /tmp
/public/uploads/
\ No newline at end of file
...@@ -42,6 +42,7 @@ group :development, :test do ...@@ -42,6 +42,7 @@ group :development, :test do
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring' gem 'spring'
gem 'pry-rails', '~> 0.3.4' gem 'pry-rails', '~> 0.3.4'
gem 'letter_opener', '~> 1.4.1'
end end
# template # template
...@@ -59,4 +60,13 @@ gem 'settingslogic', '~> 2.0.9' ...@@ -59,4 +60,13 @@ gem 'settingslogic', '~> 2.0.9'
gem 'draper', '~> 2.1.0' gem 'draper', '~> 2.1.0'
gem 'devise', '~> 3.5.1' gem 'devise', '~> 3.5.1'
\ No newline at end of file
gem 'carrierwave', '~> 0.10.0'
gem 'mini_magick', '~> 3.8.1'
# Background job
gem 'sidekiq', '~> 3.4.1'
# pagination
gem 'kaminari', '~> 0.16.3'
\ No newline at end of file
...@@ -36,6 +36,7 @@ GEM ...@@ -36,6 +36,7 @@ GEM
minitest (~> 5.1) minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4) thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1) tzinfo (~> 1.1)
addressable (2.3.8)
arel (6.0.0) arel (6.0.0)
bcrypt (3.1.10) bcrypt (3.1.10)
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
...@@ -43,6 +44,13 @@ GEM ...@@ -43,6 +44,13 @@ GEM
builder (3.2.2) builder (3.2.2)
byebug (5.0.0) byebug (5.0.0)
columnize (= 0.9.0) columnize (= 0.9.0)
carrierwave (0.10.0)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
json (>= 1.7)
mime-types (>= 1.16)
celluloid (0.16.0)
timers (~> 4.0.0)
coderay (1.1.0) coderay (1.1.0)
coffee-rails (4.1.0) coffee-rails (4.1.0)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
...@@ -52,6 +60,7 @@ GEM ...@@ -52,6 +60,7 @@ GEM
execjs execjs
coffee-script-source (1.9.1.1) coffee-script-source (1.9.1.1)
columnize (0.9.0) columnize (0.9.0)
connection_pool (2.2.0)
debug_inspector (0.0.2) debug_inspector (0.0.2)
devise (3.5.1) devise (3.5.1)
bcrypt (~> 3.0) bcrypt (~> 3.0)
...@@ -82,13 +91,14 @@ GEM ...@@ -82,13 +91,14 @@ GEM
haml (>= 4.0.6, < 5.0) haml (>= 4.0.6, < 5.0)
html2haml (>= 1.0.1) html2haml (>= 1.0.1)
railties (>= 4.0.1) railties (>= 4.0.1)
hitimes (1.2.2)
html2haml (2.0.0) html2haml (2.0.0)
erubis (~> 2.7.0) erubis (~> 2.7.0)
haml (~> 4.0.0) haml (~> 4.0.0)
nokogiri (~> 1.6.0) nokogiri (~> 1.6.0)
ruby_parser (~> 3.5) ruby_parser (~> 3.5)
i18n (0.7.0) i18n (0.7.0)
jbuilder (2.3.0) jbuilder (2.3.1)
activesupport (>= 3.0.0, < 5) activesupport (>= 3.0.0, < 5)
multi_json (~> 1.2) multi_json (~> 1.2)
jeff (1.3.0) jeff (1.3.0)
...@@ -98,16 +108,25 @@ GEM ...@@ -98,16 +108,25 @@ GEM
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
json (1.8.3) json (1.8.3)
kaminari (0.16.3)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.9.3) kgio (2.9.3)
launchy (2.4.3)
addressable (~> 2.3)
letter_opener (1.4.1)
launchy (~> 2.2)
loofah (2.0.2) loofah (2.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.6.3) mail (2.6.3)
mime-types (>= 1.16, < 3) mime-types (>= 1.16, < 3)
method_source (0.8.2) method_source (0.8.2)
mime-types (2.6.1) mime-types (2.6.1)
mini_magick (3.8.1)
subexec (~> 0.2.1)
mini_portile (0.6.2) mini_portile (0.6.2)
minitest (5.7.0) minitest (5.7.0)
multi_json (1.11.1) multi_json (1.11.2)
multi_xml (0.5.5) multi_xml (0.5.5)
mysql2 (0.3.18) mysql2 (0.3.18)
nokogiri (1.6.6.2) nokogiri (1.6.6.2)
...@@ -152,6 +171,9 @@ GEM ...@@ -152,6 +171,9 @@ GEM
rake (10.4.2) rake (10.4.2)
rdoc (4.2.0) rdoc (4.2.0)
json (~> 1.4) json (~> 1.4)
redis (3.2.1)
redis-namespace (1.5.2)
redis (~> 3.0, >= 3.0.4)
request_store (1.1.0) request_store (1.1.0)
responders (2.1.0) responders (2.1.0)
railties (>= 4.2.0, < 5) railties (>= 4.2.0, < 5)
...@@ -169,6 +191,12 @@ GEM ...@@ -169,6 +191,12 @@ GEM
rdoc (~> 4.0) rdoc (~> 4.0)
settingslogic (2.0.9) settingslogic (2.0.9)
sexp_processor (4.6.0) sexp_processor (4.6.0)
sidekiq (3.4.1)
celluloid (~> 0.16.0)
connection_pool (>= 2.1.1)
json
redis (>= 3.0.6)
redis-namespace (>= 1.3.1)
slop (3.6.0) slop (3.6.0)
spring (1.3.6) spring (1.3.6)
sprockets (3.2.0) sprockets (3.2.0)
...@@ -177,9 +205,12 @@ GEM ...@@ -177,9 +205,12 @@ GEM
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
subexec (0.2.3)
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.5) thread_safe (0.3.5)
tilt (1.4.1) tilt (1.4.1)
timers (4.0.1)
hitimes
turbolinks (2.5.3) turbolinks (2.5.3)
coffee-rails coffee-rails
twitter-bootstrap-rails (3.2.0) twitter-bootstrap-rails (3.2.0)
...@@ -212,6 +243,7 @@ PLATFORMS ...@@ -212,6 +243,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
byebug byebug
carrierwave (~> 0.10.0)
coffee-rails (~> 4.1.0) coffee-rails (~> 4.1.0)
devise (~> 3.5.1) devise (~> 3.5.1)
draper (~> 2.1.0) draper (~> 2.1.0)
...@@ -220,6 +252,9 @@ DEPENDENCIES ...@@ -220,6 +252,9 @@ DEPENDENCIES
haml-rails (~> 0.9) haml-rails (~> 0.9)
jbuilder (~> 2.0) jbuilder (~> 2.0)
jquery-rails jquery-rails
kaminari (~> 0.16.3)
letter_opener (~> 1.4.1)
mini_magick (~> 3.8.1)
mysql2 mysql2
pry-rails (~> 0.3.4) pry-rails (~> 0.3.4)
quiet_assets quiet_assets
...@@ -227,6 +262,7 @@ DEPENDENCIES ...@@ -227,6 +262,7 @@ DEPENDENCIES
sass-rails (~> 5.0) sass-rails (~> 5.0)
sdoc (~> 0.4.0) sdoc (~> 0.4.0)
settingslogic (~> 2.0.9) settingslogic (~> 2.0.9)
sidekiq (~> 3.4.1)
spring spring
turbolinks turbolinks
twitter-bootstrap-rails (~> 3.2.0) twitter-bootstrap-rails (~> 3.2.0)
...@@ -234,6 +270,3 @@ DEPENDENCIES ...@@ -234,6 +270,3 @@ DEPENDENCIES
unicorn unicorn
vacuum (~> 1.3.0) vacuum (~> 1.3.0)
web-console (~> 2.0) web-console (~> 2.0)
BUNDLED WITH
1.10.5
...@@ -12,4 +12,8 @@ ...@@ -12,4 +12,8 @@
// //
//= require jquery //= require jquery
//= require jquery_ujs //= require jquery_ujs
//= require jquery.validate.min
//= require twitter/bootstrap //= require twitter/bootstrap
//= require product
//= require ready
//= require additional-methods
@productLib = (->
@validateForm = ->
$('#form-product form').validate
rules:
'product[title]':
required: true
maxlength: 255
'product[price]':
number: true
'product[image]':
required: true
accept: "image/*"
return @
)()
\ No newline at end of file
$(document).ready ->
window.productLib.validateForm()
\ No newline at end of file
...@@ -13,4 +13,6 @@ ...@@ -13,4 +13,6 @@
*= require_self *= require_self
*= require bootstrap_and_overrides *= require bootstrap_and_overrides
*= require layout *= require layout
*= require product
*= require cart
*/ */
#cart-info{
margin-bottom: 30px;
}
\ No newline at end of file
...@@ -2,6 +2,16 @@ ...@@ -2,6 +2,16 @@
height: 22px; height: 22px;
} }
input, textarea, select{
&.error{
border-color: #FF4F4F;
}
}
label.error{
color: #FF4F4F;
}
#wrapper{ #wrapper{
margin-top: 50px; margin-top: 50px;
......
#product-detail{
.product-image img{
width: 110px;
height: 86px;
float: left;
margin: 0 20px 20px 0;
}
.product-title{
font-size: 16px;
}
}
\ No newline at end of file
...@@ -4,4 +4,14 @@ class ApplicationController < ActionController::Base ...@@ -4,4 +4,14 @@ class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception. # Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead. # For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception protect_from_forgery with: :exception
end
protected
def add_breadcrumb(title, url = nil)
@breadcrumbs = [] if @breadcrumbs.blank?
@breadcrumbs.push({title: title, url: url})
end
def add_breadcrumb_home
add_breadcrumb('Home', root_path)
end
end
\ No newline at end of file
class CartsController < ApplicationController
include CartsManagement
before_action :authenticate_user!
def index
@cart = Cart.new
end
def create
cart = current_user.carts.build(cart_params)
product_ids = []
quantites = {}
cart_params['cart_items_attributes'].each do |item|
id = item.last['product_id']
product_ids << id
quantites[id] = item.last['quantity']
end
products = Product.where(id: [product_ids]).select(:id, :price)
total = products.inject(0) do |sum, product|
sum + (product.price.to_i * quantites[product.id.to_s].to_i)
end
cart.total = total
if cart.save
clear_cart
self.send_checkout_email(cart)
redirect_to root_path
else
render :index
end
end
def send_checkout_email(cart)
CartMailer.send_checkout(current_user.email, cart).deliver_later
end
private
def cart_params
params.require(:cart).permit(:total, cart_items_attributes: [:product_id, :quantity])
end
end
\ No newline at end of file
class CategoriesController < ApplicationController
before_action :set_category, only: [:show]
def show
@products = @category.products.page(params[:page])
end
private
def set_category
@category = Category.find_by(id: params[:id])
end
end
\ No newline at end of file
module CartsManagement extend ActiveSupport::Concern
included do
def add_to_cart product
cart_item = {
'id' => product.id,
'title' => product.title,
'price' => product.price,
'quantity' => 1
}
unless session['cart_info']['items'].include?(cart_item)
session['cart_info']['items'].push(cart_item)
session['cart_info']['total'] += 1
end
end
def clear_cart
session['cart_info'] = nil
end
def session_cart
session['cart_info'].with_indifferent_access
end
end
end
\ No newline at end of file
class HomeController < ApplicationController class HomeController < ApplicationController
def index before_action :add_breadcrumb_home
@categories = Category.limit(Settings.limit_category).select(Category::JSON_DEFAULT)
def index
@recommended_items = Product.recommended @recommended_items = Product.recommended
@newest_items = Product.newest @newest_items = Product.newest
end end
......
class ProductsController < ApplicationController
include CartsManagement
before_action :set_product, only: [:show, :add_cart]
before_action :set_categories, only: [:new]
before_action :add_breadcrumb_home
before_action :authenticate_user!, only: [:new, :create]
def new
@product = Product.new
add_breadcrumb('New product')
end
def create
@product = Product.new(product_params)
if @product.save
redirect_to root_path
else
render :new
end
end
def show
add_breadcrumb(@product.category.decorate.title, category_path(@product.category))
add_breadcrumb(@product.title)
end
def add_cart
add_to_cart @product
redirect_to @product
end
private
def set_product
@product = Product.find_by(id: params[:id])
end
def set_categories
@categories = Category.all.limit(Settings.limit_category)
end
def product_params
params.require(:product).permit(:title, :price, :category_id, :image)
end
end
\ No newline at end of file
...@@ -4,4 +4,16 @@ class ProductDecorator < Draper::Decorator ...@@ -4,4 +4,16 @@ class ProductDecorator < Draper::Decorator
def price def price
return object.price || 'Contact' return object.price || 'Contact'
end end
def image_sm_url
object.amazon? ? object.image_sm_url : object.image.small.url
end
def image_md_url
object.amazon? ? object.image_md_url : object.image.medium.url
end
def image_lg_url
object.amazon? ? object.image_lg_url : object.image.large.url
end
end end
\ No newline at end of file
module ApplicationHelper module ApplicationHelper
def session_cart
(session[:cart_info] ||= {items: [], total: 0}).with_indifferent_access
end
end end
class CartMailer < ActionMailer::Base
default from: 'demo@example.com'
def send_checkout(email, cart)
@cart = cart
@cart_items = @cart.cart_items.includes(:product)
mail(to: email, subject: "Order number #{cart.id}")
end
end
\ No newline at end of file
class Cart < ActiveRecord::Base
belongs_to :user
has_many :cart_items, dependent: :destroy
accepts_nested_attributes_for :cart_items
end
class CartItem < ActiveRecord::Base
belongs_to :cart
belongs_to :product
end
...@@ -12,4 +12,6 @@ class Product < ActiveRecord::Base ...@@ -12,4 +12,6 @@ class Product < ActiveRecord::Base
validates :category, presence: true validates :category, presence: true
enum product_type: %i(system amazon) enum product_type: %i(system amazon)
mount_uploader :image, ImageUploader
end end
class User < ActiveRecord::Base class User < ActiveRecord::Base
has_many :carts
# Include default devise modules. Others available are: # Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable # :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, devise :database_authenticatable, :registerable,
......
# encoding: utf-8
require 'carrierwave/processing/mini_magick'
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
version :large do
process resize_to_fill: [110, 86]
end
version :medium do
process resize_to_fill: [71, 38]
end
version :small do
process resize_to_fill: [51, 32]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
%p= "Order ##{@cart.id}"
%p= "Total: #{@cart.total}"
%table
%thead
%tr
%td.text-right #
%td Title
%td Price
%td Quantity
%tbody
- @cart_items.each_with_index do |cart_item, index|
%tr
%td.number.text-right
= index + 1
%td.title
= link_to cart_item.product.title, product_url(cart_item.product)
%td.price
= cart_item.product.price
%td.quantity
= cart_item.quantity
\ No newline at end of file
#checkout-cart
= form_for @cart do |f|
%table.table
%thead
%tr
%td.text-right #
%td Title
%td Price
%td Quantity
%tbody
- session_cart[:items].each_with_index do |cart_item, index|
%tr
%td.number.text-right
= index + 1
%td.title
= link_to cart_item[:title], product_path(cart_item[:id])
= hidden_field_tag "cart[cart_items_attributes][#{index}][product_id]", cart_item[:id]
%td.price
= cart_item[:price]
%td.quantity
= text_field_tag "cart[cart_items_attributes][#{index}][quantity]", cart_item[:quantity]
%tfoot
%tr
%td.text-right{colspan: 4}
= f.submit 'Checkout', class: 'btn btn-primary'
= render products = render products, show_price: true
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
.product-title .product-title
= link_to product.title, product = link_to product.title, product
.product-image.img-thumbnail .product-image.img-thumbnail
= image_tag(product.image_md_url) = image_tag product.decorate.image_md_url
%h3.title
= @category.decorate.title
.module
#category-items.products-list-detail
= render @products
.pagination
= paginate @products
\ No newline at end of file
%ul.breadcrumb - if @breadcrumbs.present?
%li %ul.breadcrumb
%a{href: '#'} - @breadcrumbs.each do |breadcrumb|
Home %li= link_to_if breadcrumb[:url].present?, breadcrumb[:title], breadcrumb[:url]
%li \ No newline at end of file
%a{href: '#'}
Cate 1
\ No newline at end of file
#cart-info
%h3.title Category
= "Total: #{pluralize(session_cart[:total], 'item')}"
= link_to 'Checkout', carts_path, class: 'btn btn-default pull-right'
\ No newline at end of file
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
= link_to 'Logout', destroy_user_session_path, method: :delete = link_to 'Logout', destroy_user_session_path, method: :delete
%li %li
= link_to 'Change profile', edit_user_registration_path = link_to 'Change profile', edit_user_registration_path
%li
= link_to 'New product', new_product_path
- else - else
%li %li
......
%h3.title Category %h3.title Category
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= render @categories = render Category.limit(Settings.limit_category).select(Category::JSON_DEFAULT)
\ No newline at end of file \ No newline at end of file
...@@ -21,7 +21,13 @@ ...@@ -21,7 +21,13 @@
#content.row #content.row
.col-md-2.sidebar .col-md-2.sidebar
= render 'layouts/sidebar' .row
.col-md-12
= render 'layouts/sidebar'
.row
.col-md-12
= render 'layouts/cart'
.col-md-10 .col-md-10
= yield = yield
......
.row.product-item .row.product-item
.col-md-1 .col-md-1
.product-image.img-thumbnail .product-image.img-thumbnail
%img{src: product.image_sm_url} %img{src: product.decorate.image_sm_url}
.col-md-9 .col-md-9
.product-title .product-title
= link_to product.title, product_path(product) = link_to product.title, product_path(product)
.col-md-2 - if local_assigns.has_key?(:show_price) && show_price.present?
.product-price .col-md-2
Price: .product-price
= product.decorate.price Price:
\ No newline at end of file = product.decorate.price
\ No newline at end of file
#form-product
= form_for @product, html: {class: 'form-horizontal'} do |f|
.form-group
= f.label :title, 'Title*', class: 'col-sm-2 control-label'
.col-sm-4
= f.text_field :title, autofocus: true, class: 'form-control'
.form-group
= f.label :price, class: 'col-sm-2 control-label'
.col-sm-4
= f.text_field :price, class: 'form-control'
.form-group
= f.label :category, class: 'col-sm-2 control-label'
.col-sm-4
= f.collection_select :category_id, @categories.decorate, :id, :title, {}, class: 'form-control'
.form-group
= f.label :image, 'Image*', class: 'col-sm-2 control-label'
.col-sm-4
= f.file_field :image, class: 'form-control'
.form-group
.col-sm-offset-2.col-sm-10
= f.submit "Save", class: 'btn btn-default'
\ No newline at end of file
#product-detail
.product-title
%h4= @product.title
.product-image
= image_tag @product.decorate.image_lg_url, class: 'img-thumbnail'
.product-id
Item ID:
= @product.id
.product-price
Price:
= @product.decorate.price
.product-date
Date:
= l(@product.created_at)
.clearfix
.product-addto-cart
= link_to 'Buy', add_cart_product_path(@product), class: 'btn btn-primary'
\ No newline at end of file
...@@ -22,5 +22,7 @@ module VenShop ...@@ -22,5 +22,7 @@ module VenShop
# Do not swallow errors in after_commit/after_rollback callbacks. # Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true config.active_record.raise_in_transactional_callbacks = true
config.active_job.queue_adapter = :sidekiq
end end
end end
...@@ -40,4 +40,6 @@ Rails.application.configure do ...@@ -40,4 +40,6 @@ Rails.application.configure do
# config.action_view.raise_on_missing_translations = true # config.action_view.raise_on_missing_translations = true
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :letter_opener
end end
Kaminari.configure do |config|
config.default_per_page = 5
# config.max_per_page = nil
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
end
...@@ -21,3 +21,6 @@ ...@@ -21,3 +21,6 @@
en: en:
hello: "Hello world" hello: "Hello world"
time:
formats:
default: "%d/%m/%Y"
...@@ -2,6 +2,13 @@ Rails.application.routes.draw do ...@@ -2,6 +2,13 @@ Rails.application.routes.draw do
devise_for :users devise_for :users
root 'home#index' root 'home#index'
resources :products resources :products do
member do
get :add_cart
end
end
resources :categories resources :categories
resources :carts
end end
\ No newline at end of file
class AddImageToProducts < ActiveRecord::Migration
def change
add_column :products, :image, :string
end
end
class CreateCarts < ActiveRecord::Migration
def change
create_table :carts do |t|
t.timestamps null: false
t.references :user, index: true, null: false
t.decimal :total, default: 0
end
end
end
class CreateCartItems < ActiveRecord::Migration
def change
create_table :cart_items do |t|
t.timestamps null: false
t.references :cart, index: true
t.references :product, index: true
t.integer :quantity, default: 1
t.decimal :price, default: 0
end
end
end
class ChangeDefaultValueToProductPrice < ActiveRecord::Migration
def up
change_column :products, :price, :decimal, default: 0
end
def down
change_column :products, :price, :decimal
end
end
...@@ -11,7 +11,28 @@ ...@@ -11,7 +11,28 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150703024141) do ActiveRecord::Schema.define(version: 20150706090027) do
create_table "cart_items", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "cart_id", limit: 4
t.integer "product_id", limit: 4
t.integer "quantity", limit: 4, default: 1
t.decimal "price", precision: 10, default: 0
end
add_index "cart_items", ["cart_id"], name: "index_cart_items_on_cart_id", using: :btree
add_index "cart_items", ["product_id"], name: "index_cart_items_on_product_id", using: :btree
create_table "carts", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id", limit: 4, null: false
t.decimal "total", precision: 10, default: 0
end
add_index "carts", ["user_id"], name: "index_carts_on_user_id", using: :btree
create_table "categories", force: :cascade do |t| create_table "categories", force: :cascade do |t|
t.datetime "created_at", null: false t.datetime "created_at", null: false
...@@ -25,13 +46,14 @@ ActiveRecord::Schema.define(version: 20150703024141) do ...@@ -25,13 +46,14 @@ ActiveRecord::Schema.define(version: 20150703024141) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "asin", limit: 255 t.string "asin", limit: 255
t.string "title", limit: 255, null: false t.string "title", limit: 255
t.string "image_lg_url", limit: 255 t.string "image_lg_url", limit: 255
t.string "image_md_url", limit: 255 t.string "image_md_url", limit: 255
t.string "image_sm_url", limit: 255 t.string "image_sm_url", limit: 255
t.decimal "price", precision: 10 t.decimal "price", precision: 10, default: 0
t.integer "category_id", limit: 4, null: false t.integer "category_id", limit: 4
t.integer "product_type", limit: 4, default: 0 t.integer "product_type", limit: 4, default: 0
t.string "image", limit: 255
end end
add_index "products", ["category_id"], name: "index_products_on_category_id", using: :btree add_index "products", ["category_id"], name: "index_products_on_category_id", using: :btree
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment