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