ruby - Instance-level validations in Rails -
in pursuit add dynamic policy logic activerecord models i've attempted create way add instance-level validations. has had experience this? stuff i've searched has been less helpful. here solution came with. please critique.
# extension can used create instance-level validations. example # if have instance of 'user' can following: # @example: # user.custom_validation ->(scope) { # if scope.bad_logins >= scope.account.max_bad_logins # scope.errors.add :bad_logins, "too many bad logins account policy" # end # } # user.account.max_bad_logins = 5 # user.bad_logins = 5 # user.valid? => false # module activerecordextension module customvalidation def self.included(base) base.class_eval attr_accessor :custom_validation validate :run_custom_validation send :include, instancemethods end end module instancemethods def run_custom_validation if custom_validation custom_validation.call(self) else true end end end end end activerecord::base.send :include, activerecordextension::customvalidation
this violation of separation of concerns. you're moving model validation logic controller code. don't want controllers know what makes model valid - should pass data model , valid-or-not response back. if have validator should run on instances of model, can scope validations run when conditions set.
class user attr_accessor :enforce_login_limits validate :if => :enforce_login_limits |user| if user.bad_logins >= user.account.max_bad_logins user.errors.add :bad_logins, "too many bad logins account policy" end end end # controller user.enforce_login_limits = true user.bad_logins = 10 user.valid? # => false or, attach custom validators activemodel's existing #validates_with mechanism:
# controller/service/whatever @user.validates_with validators::badloginvalidator # lib/validators/bad_login_validator.rb class validators::badloginvalidator < activemodel::validator def validate(user) if user.bad_logins && user.bad_logins >= user.account.max_bad_logins user.errors.add :bad_logins, "too many bad logins account policy" end end end
Comments
Post a Comment