Rails Tutorial学习笔记

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容