Advice on “Dynamic” Model validation

I have a model named Calendar.

The validations that will be applied to it varies from the selections made by the user.

I know that I can use custom validation + conditional validation to do this, but doesn’t looks very clean to me.

I wonder if I can store it on a database column and pass it to a “generic” validator method.

What do you think?

Explaining further:

A user has a calendar.
Other users that have access to it calendar, can schedule appointments.

To schedule an appointment the app should validate according to the rules defined by the calendar’s owner.

There are many combinations, so what I came to is:

Create custom validator classes to each of the possible validations and make then conditional.

class Calendar
  validate_allowed_in_hollydays :appointment_date if :allowedinhollydays?
  (tenths of other cases)
  ...
end

This works, but feels wrong.

I’m thinking about storing somewhere witch rules should be applied to that calendar and then doing something like:

validate_stored_rules :appointment_date

  • Sass::SyntaxError: File to import not found or unreadable: compass in production
  • How to create a test user in test/fixtures/user.yml that can be used for integration test in Devise 4?
  • Is it the Rails way to use form helper markup?
  • event_calendar time zone
  • SSL Error When installing rubygems, Unable to pull data from 'https://rubygems.org/
  • Rails send_file multiple styles from Paperclip, how can I avoid code repetition?
  • removing 'via sendgrid.me' from mail sent using on heroku
  • Ruby/Rails - How to Create a Class and Access it from the Controller
  • 3 Solutions collect form web for “Advice on “Dynamic” Model validation”

    It seems a little backwards to save the data in the database and then validate it.

    I think your initial thought of going with some custom validation is the best bet. validates_with looks like your best option. You could then create a separate class and build all the validation inside that to keep it separate from your main model.

    class Person < ActiveRecord::Base
      validates_with GoodnessValidator
    end
    
    class GoodnessValidator < ActiveModel::Validator
      def validate
        if record.first_name == "Evil"
          record.errors[:base] << "This person is evil"
        end
      end
    end
    

    Code lifted straight from the Rails Validation Guide

    you should use with_options it allows to put default options into your code:

    class User < ActiveRecord::Base
      with_options :if => :is_admin do |admin|
        admin.validates_length_of :password, :minimum => 10
      end
    end
    

    in the example is_admin might be an database column, attr_accessor or an method

    Thank you all for your help.

    I’ve got it working like this:

    def after_initialize        
      singleton = class << self; self; end
    
      validations = eval(calendar.cofig)
    
      validations.each do |val|
        singleton.class_eval(val)
      end
    end
    
    Ruby is the best programming language in the world - Ruby on Rails.