diff --git a/README.md b/README.md index fdac827104..49256c8a91 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,39 @@ Person.delete(2) # => true Person.exists?(2) # => false ``` +### Validations + +Resources validate their attributes with Active Model validations. When a +resource is invalid, it will not issue a request: + +```ruby +class Post < ActiveResource::Base + self.site = "http://blog.io" + + validates :title, presence: true +end + +post = Post.create(title: "") # does not issue POST http://blog.io/posts.json request +post.valid? # => false +post.errors[:title] # => ["can't be blank"] +``` + +When a resource is valid but the server responds with an error, Active Resource +will add error messages in the style of Active Model validations: + +```ruby +class Post < ActiveResource::Base + self.site = "http://blog.io" + + validates :title, presence: true +end + +post = Post.create(title: "This Post is not Unique!") # issues a POST http://blog.io/posts.json request + # => {"errors":{"title":"is taken"}} +post.valid? # => false +post.errors[:title] # => ["is taken"] +``` + ### Associations Relationships between resources can be declared using the standard association syntax diff --git a/lib/active_resource/base.rb b/lib/active_resource/base.rb index 8d55b89db1..1fb8c6d8e5 100644 --- a/lib/active_resource/base.rb +++ b/lib/active_resource/base.rb @@ -322,7 +322,7 @@ module ActiveResource # # {"errors":{"first":["cannot be empty"]}} # # # - # ryan.errors.invalid?(:first) # => true + # ryan.errors.include?(:first) # => true # ryan.errors.full_messages # => ['First cannot be empty'] # # Learn more about Active Resource's validation features in the ActiveResource::Validations documentation. diff --git a/lib/active_resource/validations.rb b/lib/active_resource/validations.rb index d1a63d9300..0dd5b85af6 100644 --- a/lib/active_resource/validations.rb +++ b/lib/active_resource/validations.rb @@ -76,16 +76,56 @@ def from_xml(xml, save_cache = false) # Consider a Person resource on the server requiring both a +first_name+ and a +last_name+ with a # validates_presence_of :first_name, :last_name declaration in the model: # - # person = Person.new(:first_name => "Jim", :last_name => "") + # person = Person.new(first_name: "Jim", last_name: "") # person.save # => false (server returns an HTTP 422 status code and errors) # person.valid? # => false # person.errors.empty? # => false # person.errors.count # => 1 # person.errors.full_messages # => ["Last name can't be empty"] - # person.errors[:last_name] # => ["can't be empty"] + # person.errors[:last_name] # => ["can't be empty"] # person.last_name = "Halpert" # person.save # => true (and person is now saved to the remote service) # + # Consider a POST /people.json request that results in a 422 Unprocessable + # Content response with the following +application/json+ body: + # + # { + # "errors": { + # "base": ["Something went wrong"], + # "address": ["is invalid"] + # } + # } + # + # By default, Active Resource will automatically load errors from JSON response + # objects that have a top-level +"errors"+ key that maps attribute names to arrays of + # error message strings: + # + # person = Person.new(first_name: "Jim", last_name: "Halpert", address: "123 Fake Street") + # person.save # => false (server returns an HTTP 422 status code and errors) + # person.valid? # => false + # person.errors[:base] # => ["Something went wrong"] + # person.errors[:address] # => ["is invalid"] + # + # Consider a POST /people.xml request that results in a 422 Unprocessable + # Content response with the following +application/xml+ body: + # + # + # Something went wrong + # Address is invalid + # + # + # By default, Active Resource will automatically load errors from XML response + # documents that have a top-level ++ element that contains ++ + # children that have error message content. When an error message starts with + # an attribute name, Active Resource will automatically infer that attribute + # name and add the message to the attribute's errors. When an attribute name + # cannot be inferred, the error message will be added to the +:base+ errors: + # + # person = Person.new(first_name: "Jim", last_name: "Halpert", address: "123 Fake Street") + # person.save # => false (server returns an HTTP 422 status code and errors) + # person.valid? # => false + # person.errors[:base] # => ["Something went wrong"] + # person.errors[:address] # => ["Address is invalid"] module Validations extend ActiveSupport::Concern include ActiveModel::Validations