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

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

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

url rewriting - How to redirect a http POST with urlrewritefilter -