1.helpers帮助函数如果需要控制器和视图中同时使用的话,可以使用下面方法
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper#引用帮助函数
end
2.用户账号密码相关
①数据库指定字段唯一性
rails generate migration add_index_to_users_email
db/migrate/[timestamp]_add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration
def change
add_index :users, :email, unique: true
end
end
②加上安全密码
使用目前最先进的哈希函数 bcrypt 对密码进行不可逆的加密,得到密码的哈希值
在gemfile文件中加入
gem 'bcrypt-ruby', '3.1.7'
给用户表添加密码字段
rails generate migration add_password_digest_to_users password_digest:string
在用户模型添加中添加has_secure_password方法之后,会自动生成password 和 password_confirmation 属性,二者都要填写一些内容(非空格),而且要相等;还要定义 authenticate 方法,对比加密后的密码和 password_digest 是否一致,验证用户的身份。这对于用户验证是非常方便的。
下面是一个用户模型的示例。
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
end
到这里就可以使用rails命令行来添加用户了
$ rails console
>> User.create(name: "Michael Hartl", email: "mhartl@example.com",
?> password: "foobar", password_confirmation: "foobar")
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2013-03-11 20:45:19", updated_at: "2013-03-11 20:45:19", password_digest: "$2a$10$kn4cQDJTzV76ZgDxOWk6Je9A0Ttn5sKNaGTEmT0jU7.n...">
3.用户登录相关
①通过session来管理登录
在路由文件中添加session资源
resources :sessions, only:[:new,:create,:destroy]
表单登录文件
<% provide(:title, "Sign in") %>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
表单post提交控制器 session的create方法
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user#用户登录成功就使用该方法记住该用户
else
# Create an error message and re-render the signin form.
end
end
由于我们需要长期记录用户登录状态,最安全的做法就是为每个用户生成一个安全标示符。具体的实现方法如下:
为用户表添加一个remember_token字段,该字段记录用户的登录情况。
rails g migration add_remember_token_to_users remember_token:string
因为我们经常需要根据字段提取用户信息,所以我们也需要为该字段建立数据库索引
class AddRememberTokenToUsers < ActiveRecord::Migration
def change
add_column :users, :remember_token, :string
add_index :users, :remember_token
end
end
实现过程。首先我们先使用Ruby 标准库中 SecureRandom 模块提供的 urlsafe_base64方法生成一个长度为16的随即字符串,然后使用 SHA1 加密了记忆权标保存到数据库,用户登录时,查询用的remember_token是否和数据库中的一致,如果一致则判断为登录用户。
在User模型中添加创建remember_token的方法,在注册用户时,自动为每个用户添加一个remember_token。
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
before_create :create_remember_token
.
.
.
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.hash(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
self.remember_token = User.hash(User.new_remember_token)
end
end
再来看看我们的登录方法:
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.hash(remember_token))#更新单个属性并保存到数据库
self.current_user= user#该方法是
end
end
其中permanent方法时下面的简写模式
cookies[:remember_token] = { value: remember_token,
expires: 20.years.from_now.utc }
我们来看看current_user= 方法的定义
def current_user=(user)
@current_user = user
end
如果我们想要获取当前登录的用户,可以使用下面的方法
def current_user
remember_token = User.hash(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end
当然我们需要定义一个常用的方法来判断用户是否登录
def signed_in?
!current_user.nil?#如果方法current_user为空,current_user.nil?为真,则signed_in?返回假,即用户没有登录
end
②退出登录
方法如下
在session控制器中添加下面的方法
def destroy
sign_out
redirect_to root_path
end
在session帮助中添加下面的方法
def sign_out
#改变当前登录用户的remember_token字段的值
current_user.update_attribute(:remember_token,
User.hash(User.new_remember_token))
self.current_user = nil
cookies.delete(:remember_token)
end
4.rails分页
首先在gemfile文件中添加下面
gem 'will_paginate', '3.0.4'
添加分页插件
在控制器中:
def index
@users = User.paginate(page: params[:page], pre_page: 10)#每页显示10条记录
end
在视图中
<%= will_paginate %>
就可以直接实现分页效果了,很简单吧。。。
5.精简视图文件
<ul class="users">
<%= render @users %>
</ul>
这里的@users不是指定视图文件,而是使用哪个了@users变量。Rails 会自动去寻找一个名为 _user.html.erb 的局部视图,我们要手动创建这个视图,然后写入代码
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
</li>
Rails 会把 @users 当作一系列的 User 对象,遍历这些对象,然后使用 _user.html.erb 渲染每个对象。所以我们就得到了非常简洁的代码。
6.添加管理员用户
我们为每个添加一个字段admin,该字段为bool类型,每个用户实例都会存在一个admin?方法,所以我们可以使用该方法来判断是否为管理员,实现方法如下:
首先,我们需要为users表单添加admin字段
rails generate migration add_admin_to_users admin:boolean
当然我们也需要为该字段设定一个默认值
class AddAdminToUsers < ActiveRecord::Migration
def change
add_column :users, :admin, :boolean, default: false
end
end