Ruby on Rails实战–创建一个网上商店E用户管理模块

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

相关日志:

  1. 在Windows平台上学习Ruby on Rails 的环境准备
  2. Learning Ruby 3, Containers, Blocks, and Iterators
  3. Learning Ruby 4, Number, String and Range
  4. 用ruby语言以句子为单位拆分一个字串
  5. 太恶心了– rubygems安装gem需要使用代理服务器了
此条目发表在 Ruby on Rails 分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已被标记为 *

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>