在Rails裡,提供了一個Validation方法,供我們驗證資料格式。
我們可以直接使用,確認用戶輸入的emails的格式都是正確的。
// 編輯app/models/user.rb
class User < ActiveRecord::Base
has_secure_password
validates :email, format: { with: /\A[^@]+@[^@]+\z/}
end
validatesg是一個ActiveRecord的方法,可以讓我們限制一個屬性該有的格式或限制。
並利用regular expression(正規表示式)來確認email的格式是正確的,同時確認每一個輸入的email都是獨特的。
上面寫的Validation會在輸入或是更新資料到資料庫之前觸發,例如:
create and create!
save and save!
update and update!
另外,可以用validation去限制一筆資料是否為必填欄位:
//限制user為必填欄位,且有30字元長度上限
class User < ActiveRecord::Base
has_secure_password
validates :name, presence: true, length: {maximun: 30}
validates :email, format: { with: /\A[^@]+@[^@]+\z/}
end
再來,email是不分大小寫的,例如aaa@hotmail.com跟AAA@hotmail.com, Aaa@hotmail.com, aaa@HoTMAIL.com都是一樣的。有幾種方式可以達到這個目的:
1. callback(回呼)
class User < ActiveRecord::Base
before_save { self.email = email.downcase} # 在儲存之前,把email變成小寫。
has_secure_password
validates :name, presence: true, length: {maximun: 30}
validates :email, format: { with: /\A[^@]+@[^@]+\z/}, uniqueness: true
end
2. uniqueness: (case_sensitive: false)
另一種是直接在驗證email時加入::
class User < ActiveRecord::Base
has_secure_password
validates :name, presence: true, length: {maximun: 30}
validates :email, format: { with: /\A[^@]+@[^@]+\z/}, uniqueness: (case_sensitive: false)
end
如果要驗證email的獨特性,以上兩種方法其實還是有瑕疵,假設同一時間有兩個人同時用同一個email註冊(雖然機率很小但仍有可能),A的資料通過驗證,但尚未存入資料庫;B在同時間也用同資料通過驗證,結果這兩筆資料都被成功儲存了。
我們必須要再將email設定為索引值(index),確保資料庫在儲存之前會先查看這個email的獨特性:
$rails g migration AddUserEmailIndices
// 編輯20141023163151_add_user_email_indices
class AddUserEmailIndices < ActiveRecord::Migration
def change
add_index :users, :email, unique: true
end
end
最後執行 $rake db:migrate 更新資料庫,如此我們就可以確定所有user的email都是獨特的了。