Custom Validators
1. Validations là gì? Validations là các thao tác kiểm chứng dữ liệu hợp lệ theo các yêu cầu của người dùng trước khi được gửi lên server và lưu vào database. Ví dụ: người dùng nhập 1 form đăng ký account, thì các validations sẽ đảm bảo rằng người dùng không được bỏ trống các trường email, ...
1. Validations là gì?
Validations là các thao tác kiểm chứng dữ liệu hợp lệ theo các yêu cầu của người dùng trước khi được gửi lên server và lưu vào database. Ví dụ: người dùng nhập 1 form đăng ký account, thì các validations sẽ đảm bảo rằng người dùng không được bỏ trống các trường email, username, password. Hay email phải đúng định dạng, password có độ dài tối thiểu là 6 ...
2. Các loại validations
Rails cung cấp Validation Helpers thông dụng hoặc chúng ta có thể Custom Validations theo ý của mình.
ActiveRecord cung cấp sẵn một số Validations Helpers cho người dùng sử dụng trực tiếp như:
- Không được bỏ trống
validates :name, presence: true
- Yêu cầu checked
validates :terms_of_service, acceptance: true
- Độ dài
validates :name, length: { minimum: 2 } validates :bio, length: { maximum: 500 } validates :password, length: { in: 6..20 } validates :registration_number, length: { is: 6 }
etc...
3. Thực hiện Custom Validates
Khi các Validation Helpers không đủ cho yêu cầu sử dụng, chúng ta có thể viết các validators riêng hoặc validation method nếu bạn muốn.
3.1. Custom Validators
Custom Validators là những class kế thừa từ ActiveModel::Validator. Những class này phải implement các validate method để lấy đối số (record) và thực hiện validation nó. Custom Validator được gọi bằng validates_with method.
class MyValidator < ActiveModel::Validator def validate(record) unless record.name.starts_with? 'X' record.errors[:name] << 'Need a name starting with X please!' end end end class Person include ActiveModel::Validations validates_with MyValidator end
Cách dễ nhất để tạo một custom validator với các thuộc tính riêng là sử dụng kế thừa từ ActiveModel::EachValidator. Khi đó, class custom validator phải implement một method là validate_each gồm 3 đối số: record, attribute, and value.
class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) unless value =~ /A([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})z/i record.errors[attribute] << (options[:message] || "is not an email") end end end class Person < ApplicationRecord validates :email, presence: true, email: true end
Như trong ví dụ trên, có thể kết hợp validations cơ bản và custom validators
3.2. Custom Methods
Bạn có thể tạo ra các method để làm điều kiện kiểm tra và đưa ra messages cảnh báo. Sau đó bạn phải đăng ký các method này để sử dụng cho validates.
class Invoice < ApplicationRecord validate :active_customer, on: :create def active_customer errors.add(:customer_id, "is not active") unless customer.active? end end
4. Sử dụng Validation Errors
Rails cung cấp một số method để làm việc với các lỗi và hỏi về tính hợp lệ của object
Dưới đây một số Errors Method thường được sử dụng:
4.1. errors
Trả về các thể hiện của class ActiveModel::Errors bao gồm toàn bộ các lỗi. Mỗi key là một tên thuộc tính và giá trị của mảng là chuỗi các lỗi:
class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new person.valid? # => false person.errors.messages # => {:name=>["can't be blank", "is too short (minimum is 3 characters)"]} person = Person.new(name: "John Doe") person.valid? # => true person.errors.messages # => {}
4.2. errors[ ]
errors[ ] được dùng khi muốn in ra lỗi của một thuộc tính cụ thể:
class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new(name: "John Doe") person.valid? # => true person.errors[:name] # => [] person = Person.new(name: "JD") person.valid? # => false person.errors[:name] # => ["is too short (minimum is 3 characters)"]
4.3. errors.add
Cho phép thêm một error message liên quan đến 1 thuộc tính cụ thể. Trong đó có đối số của thuộc tính và error message:
class Person < ApplicationRecord def a_method_used_for_validation_purposes errors.add(:name, "cannot contain the characters !@#%*()_-+=") end end person = Person.create(name: "!@#") person.errors[:name] # => ["cannot contain the characters !@#%*()_-+="] person.errors.full_messages # => ["Name cannot contain the characters !@#%*()_-+="]
4.4. errors[:base]
Bạn có thể thêm error messages có liên quan đến trạng thái của toàn thể objects thay vì một thuộc tính cụ thể. Bạn có thể sử dụng phương pháp này khi muốn nói rằng object không hợp lệ mà không có vấn đề gì với các thuộc tính của nó:
class Person < ApplicationRecord def a_method_used_for_validation_purposes errors[:base] << "This person is invalid because ..." end end
4.5. errors.clear
Sử dụng khi bạn muốn xóa tất cả các messages trong danh sách lỗi. Tất nhiên, error.clear khi được gọi sẽ không làm 1 đối tượng không hợp lệ trở thành có giá trị. Nó chỉ làm rỗng danh sách các lỗi lúc này, nhưng nếu cố gắng lưu nó vào database thì validations sẽ chạy lại và danh sách các lỗi lại được đưa ra :
class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new person.valid? # => false person.errors[:name] # => ["can't be blank", "is too short (minimum is 3 characters)"] person.errors.clear person.errors.empty? # => true person.save # => false person.errors[:name] # => ["can't be blank", "is too short (minimum is 3 characters)"]
4.6. errors.size
Trả về tổng số lỗi của 1 đối tượng cụ thể:
class Person < ApplicationRecord validates :name, presence: true, length: { minimum: 3 } end person = Person.new person.valid? # => false person.errors.size # => 2 person = Person.new(name: "Andrea", email:"andrea@example.com") person.valid? # => true person.errors.size # => 0
Tổng kết : bài biết mong muốn mang lại cho các bạn cái nhìn tổng quan về validations, cách thực hiện Custom Validations và sử dụng error messages hiển thị validations
Tham khảo: http://guides.rubyonrails.org/active_record_validations.html