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

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

mysql - Pass value between different pages (form) with PHP -