Custom Validators
Bài đăng này đã không được cập nhật trong 8 năm
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
All rights reserved