Customize Validation với Validation Context
Đã 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 ...
Đã 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.