aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/validations.rb
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-03-20 21:40:37 +0000
committerPratik Naik <pratiknaik@gmail.com>2009-03-20 21:45:13 +0000
commit08a99d0eac9370b590220953283475e00e3183e6 (patch)
treee1b32a221fe5e4b0e639ff74f5c099af32da29e6 /activerecord/lib/active_record/validations.rb
parentcc5e019f6bc48663fe75a00e68293c0645998d14 (diff)
downloadrails-08a99d0eac9370b590220953283475e00e3183e6.tar.gz
rails-08a99d0eac9370b590220953283475e00e3183e6.tar.bz2
rails-08a99d0eac9370b590220953283475e00e3183e6.zip
Add I18n translations to ActiveModel and move more AR specific parts to ActiveRecord::Validations
Diffstat (limited to 'activerecord/lib/active_record/validations.rb')
-rw-r--r--activerecord/lib/active_record/validations.rb115
1 files changed, 115 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index c2e0c4a9ae..a9e6654aec 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -15,6 +15,86 @@ module ActiveRecord
end
class Errors < ActiveModel::Errors
+ class << self
+ def default_error_messages
+ message = "Errors.default_error_messages has been deprecated. Please use I18n.translate('activerecord.errors.messages')."
+ ActiveSupport::Deprecation.warn(message)
+
+ I18n.translate 'activerecord.errors.messages'
+ end
+ end
+
+ # Returns all the full error messages in an array.
+ #
+ # class Company < ActiveRecord::Base
+ # validates_presence_of :name, :address, :email
+ # validates_length_of :name, :in => 5..30
+ # end
+ #
+ # company = Company.create(:address => '123 First St.')
+ # company.errors.full_messages # =>
+ # ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Address can't be blank"]
+ def full_messages(options = {})
+ full_messages = []
+
+ each do |attribute, messages|
+ next if messages.empty?
+
+ if attribute == :base
+ messages.each {|m| full_messages << m }
+ else
+ attr_name = @base.class.human_attribute_name(attribute.to_s)
+ prefix = attr_name + I18n.t('activerecord.errors.format.separator', :default => ' ')
+ messages.each do |m|
+ full_messages << "#{prefix}#{m}"
+ end
+ end
+ end
+
+ full_messages
+ end
+
+ # Translates an error message in it's default scope (<tt>activerecord.errrors.messages</tt>).
+ # Error messages are first looked up in <tt>models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, if it's not there,
+ # it's looked up in <tt>models.MODEL.MESSAGE</tt> and if that is not there it returns the translation of the
+ # default message (e.g. <tt>activerecord.errors.messages.MESSAGE</tt>). The translated model name,
+ # translated attribute name and the value are available for interpolation.
+ #
+ # When using inheritence in your models, it will check all the inherited models too, but only if the model itself
+ # hasn't been found. Say you have <tt>class Admin < User; end</tt> and you wanted the translation for the <tt>:blank</tt>
+ # error +message+ for the <tt>title</tt> +attribute+, it looks for these translations:
+ #
+ # <ol>
+ # <li><tt>activerecord.errors.models.admin.attributes.title.blank</tt></li>
+ # <li><tt>activerecord.errors.models.admin.blank</tt></li>
+ # <li><tt>activerecord.errors.models.user.attributes.title.blank</tt></li>
+ # <li><tt>activerecord.errors.models.user.blank</tt></li>
+ # <li><tt>activerecord.errors.messages.blank</tt></li>
+ # <li>any default you provided through the +options+ hash (in the activerecord.errors scope)</li>
+ # </ol>
+ def generate_message(attribute, message = :invalid, options = {})
+ message, options[:default] = options[:default], message if options[:default].is_a?(Symbol)
+
+ defaults = @base.class.self_and_descendants_from_active_record.map do |klass|
+ [ :"models.#{klass.name.underscore}.attributes.#{attribute}.#{message}",
+ :"models.#{klass.name.underscore}.#{message}" ]
+ end
+
+ defaults << options.delete(:default)
+ defaults = defaults.compact.flatten << :"messages.#{message}"
+
+ key = defaults.shift
+ value = @base.respond_to?(attribute) ? @base.send(attribute) : nil
+
+ options = { :default => defaults,
+ :model => @base.class.human_name,
+ :attribute => @base.class.human_attribute_name(attribute.to_s),
+ :value => value,
+ :scope => [:activerecord, :errors]
+ }.merge(options)
+
+ I18n.translate(key, options)
+ end
end
module Validations
@@ -24,6 +104,8 @@ module ActiveRecord
base.send :include, ActiveModel::Validations
base.send :include, InstanceMethods
+ base.define_callbacks :validate_on_create, :validate_on_update
+
base.class_eval do
alias_method_chain :save, :validation
alias_method_chain :save!, :validation
@@ -66,10 +148,43 @@ module ActiveRecord
end
end
+ # Runs all the specified validations and returns true if no errors were added otherwise false.
+ def valid?
+ errors.clear
+
+ run_callbacks(:validate)
+
+ validate if respond_to?(:validate)
+
+ if new_record?
+ run_callbacks(:validate_on_create)
+ validate_on_create if respond_to?(:validate_on_create)
+ else
+ run_callbacks(:validate_on_update)
+ validate_on_update if respond_to?(:validate_on_update)
+ end
+
+ errors.empty?
+ end
+
# Returns the Errors object that holds all information about attribute error messages.
def errors
@errors ||= Errors.new(self)
end
+
+ def get_attribute_value(attribute)
+ respond_to?(attribute.to_sym) ? send(attribute.to_sym) : self[attribute.to_sym]
+ end
+
+ protected
+
+ # Overwrite this method for validation checks used only on creation.
+ def validate_on_create
+ end
+
+ # Overwrite this method for validation checks used only on updates.
+ def validate_on_update
+ end
end
end