aboutsummaryrefslogtreecommitdiffstats
path: root/activeresource/lib/active_resource/validations.rb
diff options
context:
space:
mode:
authorRick Olson <technoweenie@gmail.com>2006-09-08 00:07:30 +0000
committerRick Olson <technoweenie@gmail.com>2006-09-08 00:07:30 +0000
commit8d9e6609f8f67e55bba1f9bdbea62af22360dd3c (patch)
treed8315802e29467a28af7d6fb036b912cadbff587 /activeresource/lib/active_resource/validations.rb
parent7c4b6a55b61229ef5f2f053c9a88a738497c70cf (diff)
downloadrails-8d9e6609f8f67e55bba1f9bdbea62af22360dd3c.tar.gz
rails-8d9e6609f8f67e55bba1f9bdbea62af22360dd3c.tar.bz2
rails-8d9e6609f8f67e55bba1f9bdbea62af22360dd3c.zip
Basic validation support [Rick Olson]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5068 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activeresource/lib/active_resource/validations.rb')
-rw-r--r--activeresource/lib/active_resource/validations.rb125
1 files changed, 125 insertions, 0 deletions
diff --git a/activeresource/lib/active_resource/validations.rb b/activeresource/lib/active_resource/validations.rb
new file mode 100644
index 0000000000..8414e93293
--- /dev/null
+++ b/activeresource/lib/active_resource/validations.rb
@@ -0,0 +1,125 @@
+module ActiveResource
+ class ResourceInvalid < ClientError
+ end
+
+ class Errors
+ include Enumerable
+ attr_reader :errors
+
+ delegate :empty?, :to => :errors
+
+ def initialize(base) # :nodoc:
+ @base, @errors = base, {}
+ end
+
+ def add_to_base(msg)
+ add(:base, msg)
+ end
+
+ def add(attribute, msg)
+ @errors[attribute.to_s] = [] if @errors[attribute.to_s].nil?
+ @errors[attribute.to_s] << msg
+ end
+
+ # Returns true if the specified +attribute+ has errors associated with it.
+ def invalid?(attribute)
+ !@errors[attribute.to_s].nil?
+ end
+
+ # * Returns nil, if no errors are associated with the specified +attribute+.
+ # * Returns the error message, if one error is associated with the specified +attribute+.
+ # * Returns an array of error messages, if more than one error is associated with the specified +attribute+.
+ def on(attribute)
+ errors = @errors[attribute.to_s]
+ return nil if errors.nil?
+ errors.size == 1 ? errors.first : errors
+ end
+
+ alias :[] :on
+
+ # Returns errors assigned to base object through add_to_base according to the normal rules of on(attribute).
+ def on_base
+ on(:base)
+ end
+
+ # Yields each attribute and associated message per error added.
+ def each
+ @errors.each_key { |attr| @errors[attr].each { |msg| yield attr, msg } }
+ end
+
+ # Yields each full error message added. So Person.errors.add("first_name", "can't be empty") will be returned
+ # through iteration as "First name can't be empty".
+ def each_full
+ full_messages.each { |msg| yield msg }
+ end
+
+ # Returns all the full error messages in an array.
+ def full_messages
+ full_messages = []
+
+ @errors.each_key do |attr|
+ @errors[attr].each do |msg|
+ next if msg.nil?
+
+ if attr == "base"
+ full_messages << msg
+ else
+ full_messages << [attr.humanize, msg].join(' ')
+ end
+ end
+ end
+ full_messages
+ end
+
+ def clear
+ @errors = {}
+ end
+
+ # Returns the total number of errors added. Two errors added to the same attribute will be counted as such
+ # with this as well.
+ def size
+ @errors.values.inject(0) { |error_count, attribute| error_count + attribute.size }
+ end
+
+ alias_method :count, :size
+ alias_method :length, :size
+
+ def from_xml(xml)
+ clear
+ humanized_attributes = @base.attributes.keys.inject({}) { |h, attr_name| h.update(attr_name.humanize => attr_name) }
+ messages = Hash.create_from_xml(xml)['errors']['error'] rescue []
+ messages.each do |message|
+ attr_message = humanized_attributes.keys.detect do |attr_name|
+ if message[0, attr_name.size + 1] == "#{attr_name} "
+ add humanized_attributes[attr_name], message[(attr_name.size + 1)..-1]
+ end
+ end
+
+ add_to_base message if attr_message.nil?
+ end
+ end
+ end
+
+ module Validations
+ def self.included(base) # :nodoc:
+ base.class_eval do
+ alias_method_chain :save, :validation
+ end
+ end
+
+ def save_with_validation
+ save_without_validation
+ rescue ResourceInvalid
+ errors.from_xml($!.response.body)
+ end
+
+ def valid?
+ errors.empty?
+ end
+
+ # Returns the Errors object that holds all information about attribute error messages.
+ def errors
+ @errors ||= Errors.new(self)
+ end
+ end
+end \ No newline at end of file