14.3 Iteration I3: Limiting Access 14.1 Iteration I1: Adding Users
Generate empty controllers for sessions and administration
rails generate controller Sessions new create destroy
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
create app/controllers/sessions_controller.rb
route get "sessions/destroy"
route get "sessions/create"
route get "sessions/new"
invoke erb
create app/views/sessions
create app/views/sessions/new.html.erb
create app/views/sessions/create.html.erb
create app/views/sessions/destroy.html.erb
invoke test_unit
create test/functional/sessions_controller_test.rb
invoke helper
create app/helpers/sessions_helper.rb
invoke test_unit
create test/unit/helpers/sessions_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/sessions.js.coffee
invoke scss
create app/assets/stylesheets/sessions.css.scss
rails generate controller Admin index
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
create app/controllers/admin_controller.rb
route get "admin/index"
invoke erb
create app/views/admin
create app/views/admin/index.html.erb
invoke test_unit
create test/functional/admin_controller_test.rb
invoke helper
create app/helpers/admin_helper.rb
invoke test_unit
create test/unit/helpers/admin_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/admin.js.coffee
invoke scss
create app/assets/stylesheets/admin.css.scss
Implement login in and out by storing the user_id in the session
edit app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_name(params[:name])
if user and user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to admin_url
else
redirect_to login_url, alert: "Invalid user/password combination"
end
end
def destroy
session[:user_id] = nil
redirect_to store_url, notice: "Logged out"
end
end
Create the view using form_for as there is no underlying model
edit app/views/sessions/new.html.erb
<div class="depot_form">
<% if flash[:alert] %>
<p id="notice"><%= flash[:alert] %></p>
<% end %>
<%= form_tag do %>
<fieldset>
<legend>Please Log In</legend>
<div>
<%= label_tag :name, 'Name:' %>
<%= text_field_tag :name, params[:name] %>
</div>
<div>
<%= label_tag :password, 'Password:' %>
<%= password_field_tag :password, params[:password] %>
</div>
<div>
<%= submit_tag "Login" %>
</div>
</fieldset>
<% end %>
</div>
Create a landing page for the administrator
edit app/views/admin/index.html.erb
<h1>Welcome</h1>
It's <%= Time.now %>
We have <%= pluralize(@total_orders, "order") %>.
Make the orders count available to the admin page
edit app/controllers/admin_controller.rb
class AdminController < ApplicationController
def index
@total_orders = Order.count
end
end
Connect the routes to the controller actions
edit config/routes.rb
Depot::Application.routes.draw do
get 'admin' => 'admin#index'
controller :sessions do
get 'login' => :new
post 'login' => :create
delete 'logout' => :destroy
end
resources :users
resources :orders
resources :line_items
resources :carts
get "store/index"
resources :products do
get :who_bought, on: :member
end
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
root to: 'store#index', as: 'store'
# ...
end
Do a login
get /login
post /login
get http://localhost:3000/admin
Fix the sessions controller test
edit test/functional/sessions_controller_test.rb
require 'test_helper'
class SessionsControllerTest < ActionController::TestCase
test "should get new" do
get :new
assert_response :success
end
test "should login" do
dave = users(:one)
post :create, name: dave.name, password: 'secret'
assert_redirected_to admin_url
assert_equal dave.id, session[:user_id]
end
test "should fail login" do
dave = users(:one)
post :create, name: dave.name, password: 'wrong'
assert_redirected_to login_url
end
test "should logout" do
delete :destroy
assert_redirected_to store_url
end
end
rake test
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.9.2-p320/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
CartTest:
PASS add duplicate product (0.40s)
PASS add unique products (0.01s)
ProductTest:
PASS image url (0.02s)
PASS product attributes must not be empty (0.00s)
PASS product is not valid without a unique title (0.00s)
PASS product is not valid without a unique title - i18n (0.00s)
PASS product price must be positive (0.00s)
Finished in 0.441249 seconds.
7 tests, 28 assertions, 0 failures, 0 errors, 0 skips
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.9.2-p320/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
AdminControllerTest:
PASS should get index (0.34s)
CartsControllerTest:
PASS should create cart (0.01s)
PASS should destroy cart (0.08s)
PASS should get edit (0.05s)
PASS should get index (0.01s)
PASS should get new (0.01s)
PASS should show cart (0.01s)
PASS should update cart (0.01s)
LineItemsControllerTest:
PASS should create line item (0.02s)
PASS should create line item via ajax (0.11s)
PASS should destroy line item (0.01s)
PASS should get edit (0.01s)
PASS should get index (0.01s)
PASS should get new (0.01s)
PASS should show line item (0.01s)
PASS should update line item (0.01s)
OrderNotifierTest:
PASS received (0.09s)
PASS shipped (0.06s)
OrdersControllerTest:
PASS requires item in cart (0.01s)
PASS should create order (0.02s)
PASS should destroy order (0.01s)
PASS should get edit (0.01s)
PASS should get index (0.01s)
PASS should get new (0.01s)
PASS should show order (0.00s)
PASS should update order (0.01s)
ProductsControllerTest:
PASS can't delete product in cart (0.01s)
PASS should create product (0.05s)
PASS should destroy product (0.01s)
PASS should get edit (0.01s)
PASS should get index (0.01s)
PASS should get new (0.01s)
PASS should show product (0.01s)
PASS should update product (0.01s)
SessionsControllerTest:
PASS should fail login (0.09s)
PASS should get new (0.04s)
PASS should login (0.09s)
PASS should logout (0.00s)
StoreControllerTest:
PASS markup needed for store.js.coffee is in place (0.02s)
PASS should get index (0.01s)
UsersControllerTest:
PASS should create user (0.09s)
PASS should destroy user (0.00s)
PASS should get edit (0.01s)
PASS should get index (0.01s)
PASS should get new (0.01s)
PASS should show user (0.01s)
PASS should update user (0.09s)
Finished in 1.470911 seconds.
47 tests, 78 assertions, 0 failures, 0 errors, 0 skips
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
Loaded suite /home/rubys/.rvm/gems/ruby-1.9.2-p320/gems/rake-10.1.1/lib/rake/rake_test_loader
Started
DslUserStoriesTest:
PASS buying a product (0.65s)
PASS two people buying (0.14s)
UserStoriesTest:
PASS buying a product (0.07s)
Finished in 0.864904 seconds.
3 tests, 47 assertions, 0 failures, 0 errors, 0 skips
14.3 Iteration I3: Limiting Access 14.1 Iteration I1: Adding Users