Created
August 25, 2015 14:43
-
-
Save namuit/97c3c1eaf1e30c22ffb3 to your computer and use it in GitHub Desktop.
Date Validator for Ruby on Rails from http://andowebsit.es/blog/noteslog.com/post/how-to-validate-dates-in-rails-4/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class DateValidator < ActiveModel::EachValidator | |
| # EXAMPLE | |
| # class UserProfile < ActiveRecord::Base | |
| # | |
| # validates :name, presence: true | |
| # validates :birth_date, presence: true, date: {on_or_after: :birth_date_first, on_or_before: :birth_date_last} | |
| # | |
| # def self.birth_date_first | |
| # 118.years.ago | |
| # end | |
| # | |
| # def self.birth_date_last | |
| # 18.years.ago | |
| # end | |
| # end | |
| attr_accessor :computed_options | |
| def before(a, b); a < b; end | |
| def after(a, b); a > b; end | |
| def on_or_before(a, b); a <= b; end | |
| def on_or_after(a, b); a >= b; end | |
| def checks | |
| %w(before after on_or_before on_or_after) | |
| end | |
| def message_limits | |
| needs_and = | |
| (computed_options[:on_or_after] || computed_options[:after]) && | |
| (computed_options[:on_or_before] || computed_options[:before]) | |
| result = ['must be a date'] | |
| result.push('on or after', computed_options[:on_or_after]) if computed_options[:on_or_after] | |
| result.push('after', computed_options[:after]) if computed_options[:after] | |
| result.push('and') if needs_and | |
| result.push('on or before', computed_options[:on_or_before]) if computed_options[:on_or_before] | |
| result.push('before', computed_options[:before]) if computed_options[:before] | |
| result.join(' ') | |
| end | |
| def compute_options(record) | |
| result = {} | |
| options.each do |key, val| | |
| next unless checks.include?(key.to_s) | |
| if val.respond_to?(:lambda?) and val.lambda? | |
| val = val.call | |
| elsif val.is_a? Symbol | |
| if record.respond_to?(val) | |
| val = record.send(val) | |
| elsif record.class.respond_to?(val) | |
| val = record.class.send(val) | |
| end | |
| end | |
| result[key] = val.to_date | |
| end | |
| self.computed_options = result | |
| end | |
| def validate_each(record, attribute, value) | |
| return unless value.present? | |
| return unless options | |
| compute_options(record) # do not cache this | |
| # otherwise all the 'compute' thing is useless... # | |
| computed_options.each do |key, val| | |
| unless self.send(key, value, val) | |
| record.errors[attribute] << (computed_options[:message] || message_limits) | |
| return | |
| end | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment