Custom validation with rails: words with more than 26 characters
def validate if subject.split.any?{|w| w.length > 26} errors.add(:subject, "cannot have words more than 26 consecutive characters") end end
11340 users tagging and storing useful source code snippets
Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
def validate if subject.split.any?{|w| w.length > 26} errors.add(:subject, "cannot have words more than 26 consecutive characters") end end
require File.dirname(__FILE__) + '/../spec_helper' module CommentSpecHelper def valid_comment_attributes { :body => 'Some text', :commentable_type => 'School', :commentable_id => 1 } end end describe Comment do include CommentSpecHelper before(:each) do @comment = Comment.new end it "should be valid" do @comment.attributes = valid_comment_attributes @comment.should be_valid end it "should should not be valid without something to attach to" do c = valid_comment_attributes c.delete :commentable_id c.delete :commentable_type @comment.attributes = c @comment.should_not be_valid @comment.errors.on(:commentable_id).should eql("can't be blank") @comment.commentable_id = 1 @comment.should_not be_valid @comment.errors.on(:commentable_type).should eql("can't be blank") @comment.commentable_type = "School" @comment.should be_valid end it "should require body" do @comment.attributes = valid_comment_attributes.except(:body) @comment.should_not be_valid @comment.errors.on(:body).should eql("can't be blank") @comment.body = "Some text" @comment.should be_valid end it "should relate to commentable" do Comment.reflect_on_association(:commentable).should_not be_nil end it "should relate to user" do Comment.reflect_on_association(:user).should_not be_nil end end
require 'net/http' # Original credits: http://blog.inquirylabs.com/2006/04/13/simple-uri-validation/ # HTTP Codes: http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html class ActiveRecord::Base def self.validates_uri_existence_of(*attr_names) configuration = { :message => "is not valid or not responding", :on => :save, :with => nil } configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) raise(ArgumentError, "A regular expression must be supplied as the :with option of the configuration hash") unless configuration[:with].is_a?(Regexp) validates_each(attr_names, configuration) do |r, a, v| if v.to_s =~ configuration[:with] # check RegExp begin # check header response case Net::HTTP.get_response(URI.parse(v)) when Net::HTTPSuccess then true else r.errors.add(a, configuration[:message]) and false end rescue # Recover on DNS failures.. r.errors.add(a, configuration[:message]) and false end else r.errors.add(a, configuration[:message]) and false end end end end
validates_uri_existence_of :url, :with => /(^$)|(^(http|https)://[a-z0-9] ([-.]{1}[a-z0-9] )*.[a-z]{2,5}(([0-9]{1,5})?/.*)?$)/ix
# This code replumbs a few classes so that ActiveRecord accepts a wider range # of user friendly date formats. Change Date.parse_date if you need different # date input formats. To use: drop this file into ./lib, require it into # your model and then validate dates with the validates_dates validator. # # Written by Stuart Rackham <srackham@methods.co.nz> # Current version tested on Rails 1.0.0 # # Add date string parser class method to Date class. # class Date # Parse date string with one of the following formats: # # * ISO date format: yyyy-mm-dd, for example '2001-12-25' # * d[ mmm[ yy[yy]]]: examples: '22', '22 feb', '22 feb 2003', # '22 feb 03', '22 February 2003' # * +n[units] or -n[units]: Date from today: examples: '+22', '+22 days', # '+22d', '-4 weeks', '-4w', '-4week', '+6 months', '+6m', '+6month', # '-2 years', '-2y' # # The string argument is first converted to a string with #to_s. # Returns nil if passed nil or an empty string. # Raises ArgumentError if string can't be parsed. # def self.parse_date(string) string = string.to_s.strip.downcase return nil if string.empty? today = Date.today if string =~ /^(\d{4})-(\d{2})-(\d{2})$/ # ISO date format. date_array = ParseDate.parsedate(string, true) begin result = Date.new(date_array[0], date_array[1], date_array[2]) rescue raise ArgumentError end elsif string =~ /^(\d{1,2})(?:(?:\s+|-)([a-zA-Z]{3,8})(?:(?:\s+|-)(\d{2}(?:\d{2})?))?)?$/ # 'd mmmm yyyy' format and abbreviations. day = $1 month = $2 || Date::ABBR_MONTHNAMES[today.month] year = $3 || today.year date_array = ParseDate.parsedate("#{day} #{month} #{year}", true) begin result = Date.new(date_array[0], date_array[1], date_array[2]) rescue raise ArgumentError end elsif string =~ /^([+-]\d+)(?:\s*(d|days?|w|weeks?|m|months?|y|years?))?$/ # Date intervals. n = $1.to_i units = $2 || 'days' case units.first when 'd' result = today + n when 'w' result = today + n*7 when 'm' sign = n <=> 0 month = today.month + sign * (n.abs % 12) year = today.year + sign * (n.abs / 12) if month <1 month += 12 year -= 1 elsif month > 12 month -= 12 year += 1 end result = Date.new(year, month, today.day) when 'y' result = Date.new(today.year + n, today.month, today.day) end else raise ArgumentError end result end end ActiveRecord::Validations::ClassMethods.class_eval do # Validates date values, these can be dates or any formats accepted by # Date.parse_date. # # For example: # # class Person < ActiveRecord::Base # require_dependency 'date_validator' # validates_dates :birthday, # :from => '1 Jan 1920', # :to => Date.today, # :allow_nil => true # end # # Options: # * from - Minium allowed date. May be a date or a string recognized # by Date.parse_date. # * to - Maxumum allowed date. May be a date or a string recognized # by Date.parse_date. # * allow_nil - Attribute may be nil; skip validation. # def validates_dates(*attr_names) configuration = { :message => 'is an invalid date ' \ '(here are some valid examples: 23, 23 feb, 23 feb 06, ' \ '6 feb 2006, 2006-02-23, +6days, +6d, +6, +2w, -6m, +1y)', :on => :save, } configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) # Don't let validates_each handle allow_nils, it checks the cast value. allow_nil = configuration.delete(:allow_nil) from = Date.parse_date(configuration.delete(:from)) to = Date.parse_date(configuration.delete(:to)) validates_each(attr_names, configuration) do |record, attr_name, value| before_cast = record.send("#{attr_name}_before_type_cast") next if allow_nil and (before_cast.nil? or before_cast == '') begin date = Date.parse_date(before_cast) rescue record.errors.add(attr_name, configuration[:message]) else if from and date < from record.errors.add(attr_name, "cannot be less than #{from.strftime('%e-%b-%Y')}") end if to and date > to record.errors.add(attr_name, "cannot be greater than #{to.strftime('%e-%b-%Y')}") end end end end end # Override default date type cast class method to handle Date.parse_date # formats(the default implementation returns nil if passed an unrecognized date # format). # class ActiveRecord::ConnectionAdapters::Column def self.string_to_date(string) return string unless string.is_a?(String) Date.parse_date(string) rescue nil end end
# # Useful for testing Rails ActiveRecord validations. For more information see: # http://wiseheartdesign.com/articles/2006/01/16/testing-rails-validations/ # module ValidationTestHelper def assert_valid(field, message, *values) __model_check__ values.each do |value| o = __setup_model__(field, value) if o.valid? assert_block { true } else messages = [o.errors[field]].flatten assert_block("unexpected invalid field <#{o.class}##{field}>, value: <#{value.inspect}>, errors: <#{o.errors[field].inspect}>.") { false } end end end def assert_invalid(field, message, *values) __model_check__ values.each do |value| o = __setup_model__(field, value) if o.valid? assert_block("field <#{o.class}##{field}> should be invalid for value <#{value.inspect}> with message <#{message.inspect}>") { false } else messages = [o.errors[field]].flatten assert_block("field <#{o.class}##{field}> with value <#{value.inspect}> expected validation error <#{message.inspect}>, but got errors <#{messages.inspect}>") { messages.include?(message) } end end end def __model_check__ raise "@model must be assigned in order to use validation assertions" if @model.nil? o = @model.dup raise "@model must be valid before calling a validation assertion, instead @model contained the following errors #{o.errors.instance_variable_get('@errors').inspect}" unless o.valid? end def __setup_model__(field, value) o = @model.dup attributes = o.instance_variable_get('@attributes') o.instance_variable_set('@attributes', attributes.dup) o.send("#{field}=", value) o end end
def valid_cf?(cf) def ascii_displacement(ch) (?0..?9) === ch[0] ? (ch[0] - ?0) : (ch[0] - ?A) end return false if cf !~ %r{^[a-z]{6}\d{2}[abcdehlmprst]\d{2}[a-z]\d{3}[a-z]$}i sum = 0 cf[0..-2].upcase.scan(/(.)(.)?/) do |a, b| sum += [ 1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23 ][ascii_displacement(a)] sum += ascii_displacement(b) unless b.nil? end (sum % 26 + ?A) == cf[-1,1].upcase[0] end
# Note ".valid?" method must occur on object for validates_associated class ActiveForm def initialize(attributes = nil) if attributes attributes.each do |key,value| send(key.to_s + '=', value) end end yield self if block_given? end def [](key) instance_variable_get("@#{key}") end def method_missing( method_id, *args ) if md = /_before_type_cast$/.match(method_id.to_s) attr_name = md.pre_match return self[attr_name] if self.respond_to?(attr_name) end super end protected def raise_not_implemented_error(*params) ValidatingModel.raise_not_implemented_error(*params) end def self.human_attribute_name(attribute_key_name) attribute_key_name.humanize end def new_record? true end # these methods must be defined before include alias save raise_not_implemented_error alias update_attribute raise_not_implemented_error public include ActiveRecord::Validations protected # the following methods must be defined after include so that they overide # methods previously included alias save! raise_not_implemented_error class << self def raise_not_implemented_error(*params) raise NotImplementedError end alias validates_uniqueness_of raise_not_implemented_error alias create! raise_not_implemented_error alias validate_on_create raise_not_implemented_error alias validate_on_update raise_not_implemented_error alias save_with_validation raise_not_implemented_error end end require 'dispatcher' class Dispatcher class << self if ! method_defined?(:form_original_reset_application!) alias :form_original_reset_application! :reset_application! def reset_application! form_original_reset_application! Dependencies.remove_subclasses_for(ActiveForm) if defined?(ActiveForm) end end end end
class User < ActiveRecord::Base require 'validations' validates_positive_or_zero :number end
def validates_positive_or_zero(*attr_names) configuration = { :message => "Cannot be negative" } configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) validates_each attr_names do |m, a, v| m.errors.add(a, configuration[:message]) if v<0 end end