本節創建商店的用戶管理系統. 創建存放用戶資料的數據表,加入添加,刪除用戶功能, 後台管理用戶權限審查功能,和用戶登錄 退出功能.
創建用戶model: depot> ruby script/generate model user
修改depot/db/migrate/007_create_users.rb文件內容如下:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :name, :string
t.column :hashed_password, :string
t.column :salt, :string #生成密碼hash用的salt
end
end
def self.down
drop_table :users
end
end
應用depot> rake db:migrate
修改depot/app/models/user.rb文件內容如下:
require ‘digest/sha1′
#用來生成密碼hash值
class User < ActiveRecord::Base
#檢驗添加用戶表格
validates_presence_of :name,
:password,
:password_confirmation
validates_uniqueness_of :name
validates_length_of :password,
:minimum => 5,
:message => "should be at least 5 characters long"
attr_accessor :password_confirmation
#自動"再輸入一次密碼"的檢驗
validates_confirmation_of :password
# ‘password’ 是一個 virtual attribute
def password
@password
end
def password=(pwd)
@password = pwd
create_new_salt
self.hashed_password = User.encrypted_password(self.password, self.salt)
end
def self.authenticate(name, password)
user = self.find_by_name(name)
if user
expected_password = encrypted_password(password, user.salt)
if user.hashed_password != expected_password
user = nil
end
end
user
end
#安全刪除,當試圖刪除用戶表中最後一個用戶時rollback數據庫內容
def safe_delete
transaction do
destroy
if User.count.zero?
raise "Can’t delete last user"
end
end
end
private
def self.encrypted_password(password, salt)
string_to_hash = password + "wibble" + salt
Digest::SHA1.hexdigest(string_to_hash)
end
def create_new_salt
self.salt = self.object_id.to_s + rand.to_s
end
end
生成Login controller
depot> ruby script/generate controller Login add_user login logout delete_user list_users
後面接的大堆都是login裡面的actions.
depot/app/controllers/login_controller.rb文件內容為:
class LoginController < ApplicationController
#所有actions,除了login都要進行權限審查
before_filter :authorize, :except => :login
#加入admin的模板
layout"admin"
def index
@total_orders = Order.count
end
def add_user
@user = User.new(params[:user])
if request.post? and @user.save
#requset.post?用來檢驗request是否POST形式
flash[:notice] = "User #{@user.name} created"
@user = User.new
end
end
def login
session[:user_id] = nil
if request.post?
user = User.authenticate(params[:name], params[:password])
if user
session[:user_id] = user.id
#如果原來頁面存在,返回原先頁面
redirect_to(session[:original_url] || { :action => "index" })
else
flash[:notice] = "Invalid user/password combination"
end
end
end
def logout
session[:user_id] = nil
flash[:notice] = "Logged out"
redirect_to(:action => "login")
end
def delete_user
id = params[:id]
if id && user = User.find(id)
begin
#安全刪除
user.safe_delete
flash[:notice] = "User #{user.name} deleted"
rescue Exception => e
flash[:notice] = e.message
end
end
redirect_to(:action => :list_users)
end
def list_users
@all_users = User.find(:all)
end
end
修改depot/app/controllers/application.rb文件,添加用戶權限審查代碼:
class ApplicationController < ActionController::Base
private
def authorize
unless User.find_by_id(session[:user_id])
session[:original_uri] = request.request_uri #記住原來頁面
flash[:notice] = "Please log in"
redirect_to(:controller => "login", :action => "login")
end
end
end
向depot/app/controllers/admin_controller.rb文件加入審查要求:
class AdminController < ApplicationController
before_filter :authorize
#….
修改管理頁面使用的頁面模板depot/app/views/layouts/admin.rhtml,內容如下:
<html>
<head>
<title>Administer the Bookstore</title>
<%= stylesheet_link_tag "scaffold", "depot", :media => "all" %>
</head>
<body id="admin">
<div id="banner">
<img src="/images/logo.png"/>
<%= @page_title || "Pragmatic Bookshelf" %>
</div>
<div id="columns">
<div id="side">
<p>
<%= link_to "Products", :controller => ‘admin’, :action => ‘list’ %>
</p>
<p>
<%= link_to "List users", :controller => ‘login’, :action => ‘list_users’ %>
<br/>
<%= link_to "Add user", :controller => ‘login’, :action => ‘add_user’ %>
</p>
<p>
<%= link_to "Logout", :controller => ‘login’, :action => ‘logout’ %>
</p>
</div>
<div id="main">
<% if flash[:notice] -%>
<div id="notice"><%= flash[:notice] %></div>
<% end -%>
<%= @content_for_layout %>
</div>
</div>
</body>
</html>
添加用戶頁面depot/app/views/login/add_user.rhtml內容:
<div class="depot-form">
<%= error_messages_for ‘user’ %>
<fieldset>
<legend>Enter User Details</legend>
<% form_for :user do |form| %>
<p>
<label for="user_name">Name:</label>
<%= form.text_field :name, :size => 40 %>
<!–上面代碼自動生成input框–>
</p>
<p>
<label for="user_password">Password:</label>
<%= form.password_field :password, :size => 40 %>
</p>
<p>
<label for="user_password_confirmation">Confirm:</label>
<%= form.password_field :password_confirmation, :size => 40 %>
</p>
<%= submit_tag "Add User", :class => "submit" %>
<% end %>
</fieldset>
</div>
用戶登錄頁面depot/app/views/login/login.rhtml內容為:
<div class="depot-form">
<fieldset>
<legend>Please Log In</legend>
<%= start_form_tag %>
<!–form開始–>
<p>
<label for="name">Name:</label>
<%= text_field_tag :name, params[:name] %>
</p>
<p>
<label for="password">Password:</label>
<%= password_field_tag :password, params[:password] %>
</p>
<p>
<%= submit_tag "Login" %>
</p>
<%= end_form_tag %>
</fieldset>
</div>
用戶主頁depot/app/views/login/index.rhtml內容:
<h1>Welcome</h1>
It’s <%= Time.now %>.
We have <%= pluralize(@total_orders,"order") %>.
<!–pluralize自動根據@total_orders的數量決定order使用單數還是複數形式–>
用戶列表頁面depot/app/views/login/list_users.rhtml內容:
<h1>Administrators</h1>
<ul>
<% for user in @all_users %>
<li><%= link_to "[X]", { # link_to 參數
#在用戶名前自動添加刪除用戶的鏈接
:controller => ‘login’,
:action => ‘delete_user’,
:id => user},
{ # html 參數
:post => true,
:confirm => "Really delete #{user.name}?"
} %>
<%= user.name %>
</li>
<% end %>
</ul>
整理代碼:
在depot/app/controllers/store_controller.rb中加入:
before_filter :find_cart, :except => :empty_cart
def find_cart
@cart = (session[:cart] ||= Cart.new)
end
並刪除其它散雜的@cart賦值語句.
本節結束.
轉載請註明: 轉自船長日誌, 本文鏈接地址: http://www.cslog.cn/Content/ruby_on_rails_eshop_user/zh-hant/