本节创建商店的用户管理系统. 创建存放用户资料的数据表,加入添加,删除用户功能, 后台管理用户权限审查功能,和用户登录 退出功能.
创建用户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/