Trong bài này chúng ta sẽ tìm hiểu cách kiểm tra sự đúng đắn của dữ liệu.
Kiểm tra dữ liệu ở đây là kiểm tra xem dữ liệu được gửi lên có đúng với yêu cầu hay không, cũng có thể xem đây là câu lệnh catch
trong quá trình kiểm tra lỗi exception vậy, chẳng hạn như chúng ta yêu cầu người dùng nhập vào email nhưng người dùng nhập sai cấu trúc, hay upload ảnh avatar mà lại gửi lên một file PDF, nguy hiểm hơn nữa là up file ảnh giả – tức file có đuôi .jpg, .png… nhưng lại không chứa dữ liệu ảnh mà chứa mã độc… vì thế chúng ta nên kiểm tra dữ liệu được gửi lên trước khi lưu chúng vào CSDL.
Validator
Trong ứng dụng depot
mà chúng ta vừa làm trong các bài trước, chúng ta có tạo một model có tên Product,
khi tạo model thì Rails sẽ tạo một lớp cũng có tên Product
trong một file là product.rb,
và đặt file này trong thư mục app/models,
mặc định thì Rails không định nghĩa gì trong lớp này cả:
class Product < ActiveRecord::Base end
Lớp Product
được kế thừa từ lớp ActiveRecord::Base
của Rails, trong lớp ActiveRecord::Base
có một phương thức tên là validates
dùng để kiểm tra dữ liệu. Ví dụ chúng ta sửa lại đoạn code trên như sau:
class Product < ActiveRecord::Base validates :title, :description, :image_url, :presence => true end
Phương thức validates
nhận vào danh sách các thuộc tính do chúng ta định nghĩa và các phương thức kiểm tra dữ liệu, ở đây title, description
và image_url
là các thuộc tính do chúng ta định nghĩa, presence
là một phương thức kiểm tra dữ liệu, ý nghĩa của phương thức validates
này là kiểm tra xem các thuộc tính có khớp với điều kiện trong phương thức kiểm tra hay không. Ở đây presence
nhận vào
tham số true
tức là bắt buộc các thuộc tính kia không được để trống.
Bạn có thể thử chạy server, tạo một product mới và không điền gì vào 3 trường title, description, image_url
thì server sẽ thông báo lỗi:
Chúng ta thử kiểm tra một điều kiện khác như sau:
class Product < ActiveRecord::Base validates :title, :description, :image_url, :presence => true validates :price, :numericality => {:greater_than_or_equal_to => 1.0} end
Ở đây phương thức numericality
nhận vào giá trị là một đối tượng khác, đối tượng này là greater_than_or_equal_to
có giá trị 1.0, ý nghĩa là giá trị phải là số và lớn hơn 1.0.
Một phương thức kiểm tra khác là uniqueness
, ví dụ:
class Product < ActiveRecord::Base validates :title, :description, :image_url, :presence => true validates :price, :numericality => {:greater_than_or_equal_to => 1.0} validates :title, :uniqueness => true end
Ý nghĩa của phương thức này là thuộc tính phải là duy nhất, tức là không có 2 đối tượng/bản ghi nào có thuộc tính này giống nhau.
Ví dụ tiếp theo là phương thức format:
class Product < ActiveRecord::Base validates :title, :description, :image_url, :presence => true validates :price, :numericality => {:greater_than_or_equal_to => 1.0} validates :title, :uniqueness => true validates :image_url, :format => { :with => %r{\.(gif|jpg|png)\Z}i, :message => 'Chi nhan file GIF, JPG, PNG' } end
Phương thức format
này nhận vào tham số with
có giá trị là một chuỗi Regex (Regular Expression – Biểu thức chính quy), chuỗi này sẽ so sánh chuỗi giá trị với một mẫu nào đó, ở đây mẫu Regex của chúng ta có nghĩa là đường dẫn file ảnh phải kết thúc bằng .jpg, .png hoặc .gif. Ngoài ra chúng ta có thể sửa lại thuộc tính
message,
thuộc tính này sẽ in thông báo lỗi ra theo ý chúng ta muốn, thuộc tính này không bắt buộc phải có.
Ngoài ra còn có rất nhiều phương thức kiểm tra khác mà mình không đề cập ở đây, bạn có thể tham khảo tại:
http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html
Bạn cũng có thể tự viết phương thức kiểm tra riêng cho mình, nhưng mình sẽ đề cập ở bài khác.