Commit 6095a97a by Tan Phat Nguyen

Merge branch 'feature/crud_product' into 'master'

Feature/crud product

CRUD products on venshop

See merge request !1
parents c12cbfc4 52da099b
......@@ -14,3 +14,4 @@
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp
/public/uploads
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.1.7'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.3'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'rails', '4.2.0.beta4'
gem 'carrierwave', '0.10.0'
gem 'mini_magick', '3.8.0'
gem 'fog', '1.23.0'
gem 'bcrypt', '3.1.7'
gem 'faker', '1.4.2'
gem 'bootstrap-sass', '3.2.0.0'
gem 'sass-rails', '5.0.0.beta1'
gem 'uglifier', '2.5.3'
gem 'coffee-rails', '4.0.1'
gem 'jquery-rails', '4.0.0.beta2'
gem 'turbolinks', '2.3.0'
gem 'jbuilder', '2.2.3'
gem 'rails-html-sanitizer', '1.0.1'
gem 'sdoc', '0.4.0', group: :doc
gem 'mysql2'
gem 'vacuum'
gem 'kaminari'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use unicorn as the app server
# gem 'unicorn'
group :development, :test do
gem 'sqlite3', '1.3.9'
gem 'byebug', '3.4.0'
gem 'web-console', '2.0.0.beta3'
gem 'spring', '1.1.3'
gem 'pry'
end
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :test do
gem 'minitest-reporters', '1.0.5'
gem 'mini_backtrace', '0.1.3'
gem 'guard-minitest', '2.3.1'
gem 'shoulda'
end
# Use debugger
# gem 'debugger', group: [:development, :test]
group :production do
gem 'rails_12factor', '0.0.2'
gem 'unicorn', '4.8.3'
end
GEM
remote: https://rubygems.org/
specs:
actionmailer (4.1.7)
actionpack (= 4.1.7)
actionview (= 4.1.7)
actionmailer (4.2.0.beta4)
actionpack (= 4.2.0.beta4)
actionview (= 4.2.0.beta4)
activejob (= 4.2.0.beta4)
mail (~> 2.5, >= 2.5.4)
actionpack (4.1.7)
actionview (= 4.1.7)
activesupport (= 4.1.7)
rack (~> 1.5.2)
rails-dom-testing (~> 1.0, >= 1.0.4)
actionpack (4.2.0.beta4)
actionview (= 4.2.0.beta4)
activesupport (= 4.2.0.beta4)
rack (~> 1.6.0.beta)
rack-test (~> 0.6.2)
actionview (4.1.7)
activesupport (= 4.1.7)
rails-dom-testing (~> 1.0, >= 1.0.4)
rails-html-sanitizer (~> 1.0, >= 1.0.1)
actionview (4.2.0.beta4)
activesupport (= 4.2.0.beta4)
builder (~> 3.1)
erubis (~> 2.7.0)
activemodel (4.1.7)
activesupport (= 4.1.7)
rails-dom-testing (~> 1.0, >= 1.0.4)
rails-html-sanitizer (~> 1.0, >= 1.0.1)
activejob (4.2.0.beta4)
activesupport (= 4.2.0.beta4)
globalid (>= 0.3.0)
activemodel (4.2.0.beta4)
activesupport (= 4.2.0.beta4)
builder (~> 3.1)
activerecord (4.1.7)
activemodel (= 4.1.7)
activesupport (= 4.1.7)
arel (~> 5.0.0)
activesupport (4.1.7)
i18n (~> 0.6, >= 0.6.9)
activerecord (4.2.0.beta4)
activemodel (= 4.2.0.beta4)
activesupport (= 4.2.0.beta4)
arel (>= 6.0.0.beta2, < 6.1)
activesupport (4.2.0.beta4)
i18n (>= 0.7.0.beta1, < 0.8)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 1.1)
arel (5.0.1.20140414130214)
ansi (1.4.3)
arel (6.0.0.beta2)
bcrypt (3.1.7)
bcrypt (3.1.7-x64-mingw32)
binding_of_caller (0.7.3.pre1)
debug_inspector (>= 0.0.1)
bootstrap-sass (3.2.0.0)
sass (~> 3.2)
builder (3.2.2)
byebug (3.4.0)
columnize (~> 0.8)
debugger-linecache (~> 1.2)
slop (~> 3.6)
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)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
......@@ -36,95 +64,238 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.8.0)
columnize (0.8.9)
debug_inspector (0.0.2)
debugger-linecache (1.2.0)
erubis (2.7.0)
excon (0.41.0)
execjs (2.2.2)
faker (1.4.2)
i18n (~> 0.5)
ffi (1.9.6)
ffi (1.9.6-x64-mingw32)
fog (1.23.0)
fog-brightbox
fog-core (~> 1.23)
fog-json
fog-softlayer
ipaddress (~> 0.5)
nokogiri (~> 1.5, >= 1.5.11)
fog-brightbox (0.6.1)
fog-core (~> 1.22)
fog-json
inflecto
fog-core (1.24.0)
builder
excon (~> 0.38)
formatador (~> 0.2)
mime-types
net-scp (~> 1.1)
net-ssh (>= 2.1.3)
fog-json (1.0.0)
multi_json (~> 1.0)
fog-softlayer (0.3.24)
fog-core
fog-json
formatador (0.2.5)
globalid (0.3.0)
activesupport (>= 4.1.0)
guard (2.8.2)
formatador (>= 0.2.4)
listen (~> 2.7)
lumberjack (~> 1.0)
pry (>= 0.9.12)
thor (>= 0.18.1)
guard-minitest (2.3.1)
guard (~> 2.0)
minitest (>= 3.0)
hike (1.2.3)
i18n (0.6.11)
jbuilder (2.2.4)
hitimes (1.2.2)
i18n (0.7.0.beta1)
inflecto (0.0.2)
ipaddress (0.8.0)
jbuilder (2.2.3)
activesupport (>= 3.0.0, < 5)
multi_json (~> 1.2)
jeff (1.1.0)
excon (>= 0.22.1)
jquery-rails (3.1.2)
railties (>= 3.0, < 5.0)
jquery-rails (4.0.0.beta2)
rails-dom-testing (~> 1.0)
railties (>= 4.2.0.beta, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.1)
kaminari (0.16.1)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.9.2)
listen (2.7.11)
celluloid (>= 0.15.2)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
loofah (2.0.1)
nokogiri (>= 1.5.9)
lumberjack (1.0.9)
mail (2.6.3)
mime-types (>= 1.16, < 3)
method_source (0.8.2)
mime-types (2.4.3)
mini_backtrace (0.1.3)
minitest (> 1.2.0)
rails (>= 2.3.3)
mini_magick (3.8.0)
subexec (~> 0.2.1)
mini_portile (0.6.1)
minitest (5.4.2)
minitest-reporters (1.0.5)
ansi
builder
minitest (>= 5.0)
ruby-progressbar
multi_json (1.10.1)
multi_xml (0.5.5)
mysql2 (0.3.16)
rack (1.5.2)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (2.9.1)
nokogiri (1.6.4.1)
mini_portile (~> 0.6.0)
nokogiri (1.6.4.1-x64-mingw32)
mini_portile (~> 0.6.0)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
pry (0.10.1-x64-mingw32)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
win32console (~> 1.3)
rack (1.6.0.beta)
rack-test (0.6.2)
rack (>= 1.0)
rails (4.1.7)
actionmailer (= 4.1.7)
actionpack (= 4.1.7)
actionview (= 4.1.7)
activemodel (= 4.1.7)
activerecord (= 4.1.7)
activesupport (= 4.1.7)
rails (4.2.0.beta4)
actionmailer (= 4.2.0.beta4)
actionpack (= 4.2.0.beta4)
actionview (= 4.2.0.beta4)
activejob (= 4.2.0.beta4)
activemodel (= 4.2.0.beta4)
activerecord (= 4.2.0.beta4)
activesupport (= 4.2.0.beta4)
bundler (>= 1.3.0, < 2.0)
railties (= 4.1.7)
sprockets-rails (~> 2.0)
railties (4.1.7)
actionpack (= 4.1.7)
activesupport (= 4.1.7)
railties (= 4.2.0.beta4)
sprockets-rails (~> 3.0.0.beta1)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.4)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.1)
loofah (~> 2.0)
rails_12factor (0.0.2)
rails_serve_static_assets
rails_stdout_logging
rails_serve_static_assets (0.0.2)
rails_stdout_logging (0.0.3)
railties (4.2.0.beta4)
actionpack (= 4.2.0.beta4)
activesupport (= 4.2.0.beta4)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
raindrops (0.13.0)
rake (10.3.2)
rb-fsevent (0.9.4)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rdoc (4.1.2)
json (~> 1.4)
sass (3.2.19)
sass-rails (4.0.4)
ruby-progressbar (1.7.0)
sass (3.4.7)
sass-rails (5.0.0.beta1)
railties (>= 4.0.0, < 5.0)
sass (~> 3.2.2)
sprockets (~> 2.8, < 2.12)
sprockets-rails (~> 2.0)
sdoc (0.4.1)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
sprockets (2.11.3)
sass (~> 3.2)
sprockets (~> 2.12)
sprockets-rails (>= 2.0, < 4.0)
sdoc (0.4.0)
json (~> 1.8)
rdoc (~> 4.0, < 5.0)
shoulda (3.5.0)
shoulda-context (~> 1.0, >= 1.0.1)
shoulda-matchers (>= 1.4.1, < 3.0)
shoulda-context (1.2.1)
shoulda-matchers (2.7.0)
activesupport (>= 3.0.0)
slop (3.6.0)
spring (1.1.3)
sprockets (2.12.3)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.2.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0)
sqlite3 (1.3.10)
sqlite3 (1.3.10-x64-mingw32)
sprockets-rails (3.0.0.beta1)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (~> 2.8)
sqlite3 (1.3.9)
sqlite3 (1.3.9-x64-mingw32)
subexec (0.2.3)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
turbolinks (2.5.1)
timers (4.0.1)
hitimes
turbolinks (2.3.0)
coffee-rails
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.5.3)
execjs (>= 0.3.0)
json (>= 1.8.0)
unicorn (4.8.3)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
vacuum (1.1.1)
jeff (~> 1.0)
multi_xml (~> 0.5.0)
web-console (2.0.0.beta3)
activemodel (~> 4.0)
binding_of_caller (= 0.7.3.pre1)
railties (~> 4.0)
sprockets-rails (>= 2.0, < 4.0)
win32console (1.3.2)
PLATFORMS
ruby
x64-mingw32
DEPENDENCIES
coffee-rails (~> 4.0.0)
jbuilder (~> 2.0)
jquery-rails
bcrypt (= 3.1.7)
bootstrap-sass (= 3.2.0.0)
byebug (= 3.4.0)
carrierwave (= 0.10.0)
coffee-rails (= 4.0.1)
faker (= 1.4.2)
fog (= 1.23.0)
guard-minitest (= 2.3.1)
jbuilder (= 2.2.3)
jquery-rails (= 4.0.0.beta2)
kaminari
mini_backtrace (= 0.1.3)
mini_magick (= 3.8.0)
minitest-reporters (= 1.0.5)
mysql2
rails (= 4.1.7)
sass-rails (~> 4.0.3)
sdoc (~> 0.4.0)
sqlite3
turbolinks
uglifier (>= 1.3.0)
pry
rails (= 4.2.0.beta4)
rails-html-sanitizer (= 1.0.1)
rails_12factor (= 0.0.2)
sass-rails (= 5.0.0.beta1)
sdoc (= 0.4.0)
shoulda
spring (= 1.1.3)
sqlite3 (= 1.3.9)
turbolinks (= 2.3.0)
uglifier (= 2.5.3)
unicorn (= 4.8.3)
vacuum
web-console (= 2.0.0.beta3)
# 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/
# 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/
# 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/
$(document).ready ->
$('#product_photo').bind 'change', ->
size_in_megabytes = this.files[0].size/1024/1024
if (size_in_megabytes > 5)
alert('Maximum file size is 5MB. Please choose a smaller file.')
\ No newline at end of file
// Place all the styles related to the admin/products controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
// Place all the styles related to the category controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
@import "bootstrap-sprockets";
@import "bootstrap";
.navbar-fixed-top {
border: 0;
}
.sidebar {
display: none;
}
.sidebar {
position: fixed;
top: 51px;
bottom: 0;
left: 0;
z-index: 1000;
display: block;
padding: 20px;
overflow-x: hidden;
overflow-y: auto;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
.nav-sidebar {
margin-right: -21px;
margin-bottom: 20px;
margin-left: -20px;
}
.nav-sidebar > .active > a, .nav-sidebar > .active > a:hover, .nav-sidebar > .active > a:focus {
color: #fff;
background-color: #428bca;
}
.nav-sidebar > li > a {
padding-right: 20px;
padding-left: 20px;
}
.main {
padding: 75px;
}
.main {
padding-right: 40px;
padding-left: 40px;
}
.main .page-header {
margin-top: 0;
}
.placeholders {
margin-bottom: 30px;
text-align: center;
}
.sub-header {
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
#error_explanation {
color: red;
ul {
color: red;
margin: 0 0 30px 0;
}
}
h4 {
color: #428bca;
}
h2 {
color: #428bca;
}
.price-col {
color: #b12704;
}
\ No newline at end of file
// Place all the styles related to the home controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
class Admin::ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
def index
@products = Product.all
end
def new
@product = Product.new
end
def create
@product = Product.new(product_params)
if @product.save
redirect_to [:admin, @product]
else
render :new
end
end
def show
end
def edit
end
def update
if @product.update_attributes(product_params)
redirect_to [:admin, @product]
else
render :edit
end
end
def destroy
@product.destroy
redirect_to admin_products_path
end
private
def product_params
params.require(:product).permit(:name, :price, :description, :category_id, :photo, :remote_photo_url)
end
def set_product
@product = Product.find(params[:id])
end
end
......@@ -2,4 +2,12 @@ class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
private
def record_not_found
redirect_to root_path
end
end
class CategoriesController < ApplicationController
def show
@category = Category.find(params[:id])
@products = @category.products.page(params[:page])
end
end
class HomeController < ApplicationController
def index
@categories = Category.all
end
end
class ProductsController < ApplicationController
def show
@product = Product.find(params[:id])
end
end
module Admin::ProductsHelper
end
module ApplicationHelper
def full_title(page_title = '')
base_title = "VenShop Deploy Application"
if page_title.empty?
base_title
else
"#{page_title} | #{base_title}"
end
end
end
module CategoriesHelper
end
module HomeHelper
end
module ProductsHelper
end
class Category < ActiveRecord::Base
has_many :products, dependent: :destroy
def newest_products
products.newest
end
end
class Product < ActiveRecord::Base
belongs_to :category
validates :name, presence: true, length: { maximum: 50 }
validates :price, presence: true, numericality: true,
format: { with: /\A\d+(?:\.\d{0,2})?\z/ }
validates :description, presence: true
validate :photo_size
scope :newest, -> { order(created_at: :desc).limit(4) }
mount_uploader :photo, ImageUploader
paginates_per 8
private
def photo_size
if photo.size > 5.megabytes
errors.add(:photo, "should be less than 5MB")
end
end
end
# encoding: utf-8
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process resize_to_limit: [400, 400]
# 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
def extension_white_list
%w(jpg jpeg gif png)
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 :thumb do
# process :resize_to_fit => [50, 50]
# 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
<%= form_for [:admin, @product], html: { multipart: true } do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="form-group">
<%= image_tag @product.photo.url, width: '140', height: '140', class: 'img-rounded' %>
</div>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: 'Name of Item' %>
</div>
<div class="form-group">
<%= f.label :price %>
<%= f.text_field :price, class: 'form-control', placeholder: 'Price of Item' %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.text_area :description, class: 'form-control', placeholder: 'Description' %>
</div>
<div class="form-group">
<%= f.label :category %>
<%= f.select :category_id, Category.all.collect { |category| [category.name, category.id] } %>
</div>
<div class="form-group">
<%= f.label :photo %>
<%= f.file_field :photo, accept: 'image/jpeg,image/gif,image/png' %>
</div>
<div class="form-group">
<%= f.label :remote_photo_url, "or photo URL" %> <br>
<%= f.text_field :remote_photo_url %>
</div>
<%= f.submit class: "btn btn-primary" %>
<%= link_to 'Cancel', admin_products_path, class: "btn btn-primary" %>
<% end %>
\ No newline at end of file
<tr>
<td><%= product.name %></td>
<td><%= product.price %></td>
<td><%= product.description %></td>
<td><%= product.category.name %></td>
<td><%= image_tag product.photo_url.to_s, width: '140', height: '140', class: 'img-rounded' %></td>
<td><%= link_to 'Show', [:admin, product] %></td>
<td><%= link_to 'Edit', edit_admin_product_path(product) %></td>
<td><%= link_to 'Destroy', [:admin, product], method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% provide(:title, "Edit Product") %>
<h1 class='page-header'>Edit Product</h1>
<%= render 'form' %>
\ No newline at end of file
<% provide(:title, 'Product Lists') %>
<h1 class='page-header'>Item Management</h1>
<div class='table-responsive'>
<table class='table table-striped'>
<tr>
<th>Name</th>
<th>Price</th>
<th>Description</th>
<th>Category</th>
<th>Photo</th>
<th colspan='3'></th>
</tr>
<%= render @products %>
</table>
</div>
<%= link_to 'New Product', new_admin_product_path, class: "btn btn-primary" %>
\ No newline at end of file
<% provide(:title, 'New Product') %>
<h1 class='page-header'>Add New Product</h1>
<%= render 'form' %>
\ No newline at end of file
<% provide(:title, @product.name) %>
<h1 class='page-header'>Show Product</h1>
<p>Name: <b><%= @product.name%></b></p>
<p>Price: <b>$<%= @product.price%></b></p>
<p>Description: <b><%= @product.description%></b></p>
<p>Category: <b><%= @product.category.name%></b></p>
<%= image_tag @product.photo.url, width: '140', height: '140', class: 'img-rounded' %> <br/><br>
<%= link_to 'Back', admin_products_path, class: 'btn btn-primary' %>
<%= link_to 'Edit', edit_admin_product_path(@product), class: 'btn btn-primary' %>
\ No newline at end of file
<% if category.products.any? %>
<h2 class='sub-header'><%= category.name %></h2>
<div class='row placeholders'>
<%= render category.newest_products %>
</div>
<div>
<%= link_to '>>View more...', category_path(category) %>
</div>
<% end %>
\ No newline at end of file
<%= provide(:title, "Category #{@category.name if @category}") %>
<h1 class='page-header'>Category <%= @category.name if @category %></h1>
<div class='row placeholders'>
<%= render @products %>
</div>
<%= paginate @products %>
\ No newline at end of file
<%= provide(:title, 'Home') %>
<h1 class='page-header'>VenShop Apps</h1>
<%= render @categories %>
\ No newline at end of file
<footer class="footer">
<small>
The Venshop 2014 by <a href="http://wwww.zigexn.vn">Zigexn</a>
</small>
<nav>
<ul>
<li><%= link_to 'About', '#' %></li>
<li><%= link_to 'Contact', '#' %></li>
<li><a href="http://zigexn.vn">Zigexn VeNtura</a></li>
</ul>
</nav>
</footer>
\ No newline at end of file
<nav class='navbar navbar-inverse navbar-fixed-top'>
<div class='container-fluid'>
<div class='navbar-header'>
<%= link_to 'VenShop Apps', root_path, class: 'navbar-brand' %>
</div>
<div id='navbar' class='navbar-collapse collapse'>
<ul class='nav navbar-nav navbar-right'>
<li><%= link_to 'Home', root_path %></li>
<li><%= link_to 'Log in', '#' %></li>
<li><%= link_to 'Register', '#' %></li>
</ul>
<form class='navbar-form navbar-right'>
<input type='text' class='form-control' placeholder='Search...'>
</form>
</div>
</div>
</nav>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
</head>
<body>
<%= render 'layouts/header' %>
<%= yield %>
<div class='container-fluid'>
<div class='row'>
<div class='col-sm-3 col-md-2 sidebar'>
<ul class='nav nav-sidebar'>
<li class='active'><a href='#'>Categories</a></li>
<% Category.all.each do |category| %>
<li><%= link_to category.name, category_path(category) %></li>
<% end %>
</ul>
</div>
<div class='col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main'>
<%= yield %>
</div>
</div>
</div>
</body>
</body>
<%= render 'layouts/footer' %>
</html>
<div class='col-xs-6 col-sm-3 placeholder'>
<div style='height: 234px;'>
<%= image_tag product.photo_url.to_s, width: '140', height: '140', class: 'img-thumbnail' %>
</div>
<h4><%= link_to product.name, product_path(product) %></h4>
<span class='price-col'>$<%= product.price %></span>
</div>
\ No newline at end of file
<% provide(:title, "Item detail") %>
<% if @product %>
<h1 class='page-header'><%= @product.name %></h1>
<div class='page-header row'>
<div class='col-xs-4'>
<%= image_tag @product.photo_url.to_s, width: '349', height: '500', class: 'img-rounded' %>
</div>
<div class='col-xs-8'>
Item: <h4><%= @product.name %></h4>
Price: <p class='price-col'>$<%= @product.price %></p>
Date: <p><%= @product.created_at.strftime('%d-%m-%Y') %></p>
</div>
</div>
<div class='row'>
<b>Description:</b>
<p></p>
<p><%= @product.description %></p>
</div>
<div class='row'>
<%= link_to 'Buy', '#', class: 'btn btn-primary' %>
</div>
<% end %>
\ No newline at end of file
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
\ No newline at end of file
Rails.application.routes.draw do
namespace :admin do
resources :products
end
get 'amazon/welcome'
get 'amazon/index'
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
get '/category/:id', to: 'categories#show', as: 'category'
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
resources :products, only: [:show]
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
get 'home' => 'home#index'
root 'home#index'
end
class AddImageToProducts < ActiveRecord::Migration
def change
add_column :products, :photo, :string
end
end
class ChangeScalePriceInProducts < ActiveRecord::Migration
def change
change_column :products, :price, :decimal, precision: 10, scale: 2
end
end
......@@ -11,21 +11,22 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20141110030316) do
ActiveRecord::Schema.define(version: 20141111033549) do
create_table "categories", force: true do |t|
t.string "name"
t.string "name", limit: 255
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "products", force: true do |t|
t.string "name"
t.decimal "price", precision: 10, scale: 0
t.text "description"
t.integer "category_id"
t.string "name", limit: 255
t.decimal "price", precision: 10, scale: 2
t.text "description", limit: 65535
t.integer "category_id", limit: 4
t.datetime "created_at"
t.datetime "updated_at"
t.string "photo", limit: 255
end
add_index "products", ["category_id"], name: "index_products_on_category_id", using: :btree
......
require 'test_helper'
class Admin::ProductsControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
end
test "should get show" do
get :show
assert_response :success
end
test "should get new" do
get :new
assert_response :success
end
test "should get create" do
get :create
assert_response :success
end
test "should get edit" do
get :edit
assert_response :success
end
test "should get update" do
get :update
assert_response :success
end
test "should get destroy" do
get :destroy
assert_response :success
end
end
require 'test_helper'
class CategoriesControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end
require 'test_helper'
class HomeControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end
require 'test_helper'
class ProductsControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end
require 'test_helper'
class ProductsHelperTest < ActionView::TestCase
end
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