-
Notifications
You must be signed in to change notification settings - Fork 5
Home
This is a forked repository. Have a look at
humaneq’s hyperactiveresource wiki
for more information.
HyRes is aimed at Rails 2.3.X which does not have modular Validations (as Rails 3.0 does).
So for HyRes’s validations etc to work you must replace your copy of ActiveResource’s validations.rb with the (stripped down) code to follow.
For Use with Rails 3.0… stay tuned.
module ActiveResource class RecordInvalid < ClientError #:nodoc: attr_reader :record def initialize(record) @record = record super("Validation failed: #{@record.errors.full_messages.join(", ")}") end end class ResourceInvalid < ClientError #:nodoc: end # Module to support validation and errors with Active Resource objects. The module overrides # Base#save to rescue ActiveResource::ResourceInvalid exceptions and parse the errors returned # in the web service response. The module also adds an +errors+ collection that mimics the interface # of the errors provided by ActiveRecord::Errors. # # ==== Example # # Consider a Person resource on the server requiring both a +first_name+ and a +last_name+ with a # <tt>validates_presence_of :first_name, :last_name</tt> declaration in the model: # # 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.on(:last_name) # => "can't be empty" # person.last_name = "Halpert" # person.save # => true (and person is now saved to the remote service) # module Validations def self.included(base) # :nodoc: base.class_eval do alias_method_chain :save, :validation end end # Validate a resource and save (POST) it to the remote web service. def save_with_validation(perform_validation = true) # clear the remote validations so they don't interfere with the local # ones. Otherwise we get an endless loop and can never change the # fields so as to make the resource valid @remote_errors = nil if perform_validation && valid? || !perform_validation save_without_validation true else false end rescue ResourceInvalid => error @remote_errors = error.response.body errors.from_xml(@remote_errors) false end # overload the Active Record valid? method to reload any remote errors we # still have hanging around since the last time we touched the remote # system def valid? super errors.from_xml(@remote_errors, true) if defined?(@remote_errors) && @remote_errors errors.empty? end end end
There’s a TODO list on the README file – I’ll update those as I go.
There’s one known bug(that I know):
steps to reproduce:
Site < HyperactiveResource
self.site = ‘http://localhost:3000/’
endSite.create()
fails with a 500 internal server error (see backtrace at bottom) because the remote API receives: Parameters: {"site"=>"\n"}
So – creating a new thing with an empty set of attributes fails miserably.
Looking at ARes it encodes just the same xml as HyRes… but for some reason ARes never actually sends a create request for an empty object…
It looks like the issue is actually Hash::to_xml which can be shown thus:
>> my_hash = {}
=> {}
>> my_hash.to_xml
=> “<?xml version=\”1.0\" encoding=\“UTF-8\”?>\n\n\n"
The remote site interprets this as: Parameters: {"hash"=>"\n"}
and can’t interpret the “\n” back into a hash as it automatically tries to stringify_keys! (which, of course, a string doesn’t have). :P
so the workaround is to always make sure there is at least one field filled in… not so good if you need to get a valid id before entering stuff… but ok for most normal situations.
backtrace follows:
ActiveResource::ServerError: Failed with 500 Internal Server Error
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/connection.rb:180:in `handle_response’
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/connection.rb:151:in `request’
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/connection.rb:134:in `post’
from /home/taryn/projects/partnerportal/vendor/plugins/hyperactiveresource/lib/hyperactive_resource.rb:340:in `create’
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/base.rb:796:in `save_without_validation’
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/validations.rb:43:in `save’
from /home/taryn/projects/partnerportal/vendor/plugins/hyperactiveresource/lib/hyperactive_resource.rb:209:in `save’
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/base.rb:465:in `create’
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/base.rb:465:in `tap’
from /usr/lib/ruby/gems/1.8/gems/activeresource-2.3.2/lib/active_resource/base.rb:465:in `create’
from (irb):1