RailsTutorial-筆記6-用戶認證

demo6 auth-user 用戶與認證(註冊)

rails tutorial 3rd 第六章 用戶模型
託管: https://bitbucket.org/imedingyiming/demo6-auth-user
省略初始化了,每次都會練一遍,文檔中就不描述了,順當多了,開始記錄些重點吧.git

用戶模型

  • 生成github

//控制器生成
rails g controller Users new

//模型類生成
rails g model User name:string email:string
  • 遷移文件正則表達式

db/migrate/[timestamp]_create_users.rb

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timstamps null: false
    end
  end
end

// 表名複數,模型名單數
  • 向上遷移算法

bundle exec rake db:migrate

//回滾
bundle exec db:rollback
  • 模型文件數據庫

app/models/user.rb
  class User < ActiveRecord::Base
  end
  • 模型對象的操做express

rails console --sandbox

//新建
user = User.new(name: "xxx", email: "xxx")
user.valid?  => true
user.save  => true
user  =>  結果集
user.name  => xxx
foo = User.create(name: "xx", email:"xx") => 結果集

//刪除
foo.destroy   => 結果集
foo  => 結果集,銷燬的對象還在內存中

// 查找
User.find(1) => 結果集
User.find_by(email: "xxx")  => 結果集
User.first   => 第一條結果集
User.all     => 所有結果集

//更新
user.email = "xxxx"  => 賦新值
user.reload.email  => 使用數據庫中數據從新加載對象
//更新的第二種方法
user.update_attributes(name: "xxx",email: "xx")  => true

用戶數據驗證

  • 有效性測試安全

//test/models/user_test.rb
def setup
  @user = User.new(name: "xxx",email: "xxx")
end
test "should be valid" do
  assert @user.valid?
end

bundle exec rake test:models  //只運行模型測試
  • 存在性驗證ruby

//test/models/user_test.rb
...
test "name should be present"
  @user.name = " "
  assert_not @user.valid?
end

//app/models/user.rb
validates :name,presence: true
  • 長度驗證app

test "name should not be too long" do
  @user.email = "a" * 51
  assert_not @user.valid?
end

test "email should not be too long" do
  @user.email = "a"*256
  assert_not @user.valid?
end

validates :name,presence:true,length: { maximum:50 }
validates :email,presences:true,length: { maximum:255 }
  • 格式驗證測試

test "email validation should accepte valid addresses" do
  valid_addresses = %w[user@exampel.com USER@foo.COM A_US-ER@foo.bar.org
                       first.last@foo.jp alice+bob@baz.cn]
  valid_addresses.each do |valid_address|
    @user.email = valid_address
    assert @user.valid?, "#{valid_address.inspect} should be valid"
  end
end
  • 郵箱正則

/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i        完整的正則表達式
/                                           正則表達式開始
\A                                          匹配字符串的開頭
[\w+\-.]+                                   一個或多個字母,加好,連字符,或點號
@                                           匹配@符號
[a-z\d\-.]+                                 一個或多個字母,數字,連字符或點號
\.                                          匹配點號
[a-z]+                                      一個或多個字母
\z                                          匹配字符串結尾
/                                           結束正則表達式
i                                           不區分大小寫

Rubular ruby regular expression editor 練習正則

bundle exec rake test:models
  • 惟一性驗證

test "拒絕重複電子郵件地址" do
  duplicate_user = @user.dup  //建立重複對象
  duplicate_user.email = @user.email.upcase //不區分大小寫
  @user.save
  assert_not duplicate_user.valid?
end

validates :email,uniqueness: true  //惟一性
validates :email,uniqueness: { case_sensitive: false } //不區分大小寫的惟一性驗證,自動爲true

數據庫索引

  • 建立遷移文件

rails g migration add_index_to_users_email

// db/migrate/[timestamp]_add_index_to_users_email.rb
def change
  add_index :users, :email, unique: true
end

bundle exec rake db:migrate
  • eamil保存前存爲小寫

before_save { self.email = email.downcase }

添加安全密碼

class User < ActiveRecord::Base
  ...
  has_secure_password
end
  • has_secure_password方法,會添加以下功能:

    • 在數據庫中的password_digest 列存儲安全的密碼哈希值

    • 得到一對"虛擬屬性",password和password_confirmation,並且建立對象時會執行存在下驗證和匹配驗證

    • 得到authenticate方法,若是密碼正確,返回對應的用戶對象,不然返回false

  • has_secure_password發揮功效的惟一要求是,模型中字段名爲password_digest屬性

  • 遷移命名

rails g migration add_password_digest_to_users password_digest:string

//生成
def change
  add_column :users, :password_digest, :string
end

bundle exec rake db:migrate
  • 添加bcrypt 哈希算法計算密碼

//Gemfile
gem 'bcrypt', '3.1.7'

bundle install
  • 添加密碼測試

def setup
    @user = User.new(name: "user",
                     email: "user@example.com",
                     password: "foobar",
                     password_confirmation: "foobar")
  end
  • 密碼的最短長度

//雙重賦值
test "密碼最短長度" do
  @user.password = @user.password_confirmation = "a" * 5
  assert_not @user.valid?
end

validates :password,length: { minimum: 6 }

建立並認證用戶

rails c
User.create(name:"xxx",email: "wode@example.com",password: "111111",password_confirmation: "111111")
user = User.find_by(name:"xxx")
user.password_digest
user.authenticate("111111")  => 結果集,不對則爲false
!!user.authenticate("111111") => true

推送

bundle exec rake test
git add -A
git commit -m "finish demo6"
git checkout master
git push origin master
git push heroku master
heroku run rake db:migrate
heroku run console --sandbox
User.create(...)

第六章小結

  • 使用遷移能夠修改應用的數據模型

  • ActiveRecord 提供了不少建立和處理數據模型的方法

  • 使用ActiveRecord驗證能夠在模型的數據上添加約束條件

  • 常見的驗證有存在性,長度,格式

  • 正則表達式

  • 數據庫索引能夠提高查詢效率,並且能在數據庫層實現惟一性約束

  • 能夠使用內置的has_secure_password 方法在模型中添加一個安全的密碼

練習

  • 切分支

git checkout -b demo6-exe
  • 郵箱小寫形式測試

test "email addresses should be saved as lower-case" do
  mixed_case_email = "Foo@ExAMPle.CoM"
  @user.email = mixed_case_email
  @user.save
  assert_equal mixed_case_email.downcase,@user.reload.email
end
  • before_save回調的另外一種實現方式

before { email.downcase! }
  • 不容許電子郵件多個點號的正則

/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
相關文章
相關標籤/搜索