Customize Validation với Validation Context
Bài đăng này đã không được cập nhật trong 7 năm
Đã bao giờ bạn tự hỏi làm thế nào để bỏ qua một hoặc nhiều validation trong một số trường hợp nhất định? Và hôm nay, tôi sẽ cùng các bạn tìm cách để giải quyết vấn đề này nhé. Điều đầu tiên nảy ra trong đầu tôi khi gặp vấn đề này là gán điều kiện cho validation. và chúng ta hãy thử xem.
tôi có 1 model là User
class User < ActiveRecord::Base
validates_length_of :slug, minimum: 3
end
và bây giờ tôi chỉ muốn thực hiện validate này với user thường chứ không phải admin. tôi sẽ thực hiện như sau:
class User < ActiveRecord::Base
attr_accessor: :edited_by_admin
validates_length_of :slug, minimum: 3, unless: Proc.new{|u| u.edited_by_admin? }
end
và ở trên controller tôi sẽ gán edited_by_admin = true
class Admin::UsersController
def edit
@user = User.find(params[:id])
@user.edited_by_admin = true
if @user.save
redirect # ...
else
render # ...
end
end
end
và bây giờ đoạn code này đã có thể đáp ứng nhu cầu của tôi, nhưng nó vẫn còn dài dòng và khó hiểu. Nên tôi sẽ giới thiệu đến các bạn Validation Context: vẫn với yêu cầu trên nhưng tôi chỉ cần thực hiện như sau
class User < ActiveRecord::Base
validates_length_of :slug, minimum: 3, on: :user
end
class User < ActiveRecord::Base
class Admin::UsersController
def edit
@user = User.find(params[:id])
if @user.save(context: :admin)
redirect # ...
else
render # ...
end
end
end
rất đơn giản phải không nào, và nếu bạn chỉ muốn kiểm check validation mà không lưu lại:
u = User.new
u.valid?(:admin)
# or
u.valid?(:user)
Chú ý: Nếu bạn muốn có một số validations thực trên:: admin và một số trên::create thì code sẽ làm việc theo cách bạn muốn. Ví dụ:
class User < ActiveRecord::Base
validates_length_of :slug, minimum: 3, on: :user
validates_length_of :slug, minimum: 1, on: :admin
validate :something, on: :create
end
Khi bạn chạy user.valid?(:admin) hay user.save(context: admin) cho bản ghi mới, thì hệ thống sẽ kích hoạt validation cuối cùng. Và có một mẹo nhỏ nếu bạn muốn valid cả context mặc định(như: create, update, destroy) và custome context như :admin như sau:
class Admin::UsersController
def edit
User.transaction do
@user = User.find(params[:id])
if @user.valid?(:admin) && @user.valid?(:create)
@user.save!(validate: false)
redirect # ...
else
render # ...
end
end
end
end
Trên đây là những giới thiệu ngắn gọn về Validation Context với Ruby on Rails, cảm ơn các bạn đã dành thời gian theo dõi.
All rights reserved