Reserve Usernames ============================== This is an engine that adds support to leap_web for checking an external REST API to see if a username is available. Once the account is created, the username is reserved via the same external API. TODO: * support the ability for a user to change their username * sanitize error messages before displaying See the file config.yml for the development and production values used for accessing the remote API. This gem is distributed on the same license as leap_web. Notes -------------------------------- This engine uses ActiveResource, which maps a ActiveRecord-like interface to a REST API. So, the remote API must conform to the API expected by ActiveResource. * http://rubydoc.info/gems/activeresource/3.2.18/frames * http://api.rubyonrails.org/v3.2.18/files/activeresource/README_rdoc.html * https://github.com/rails/activeresource ActiveResource exceptions: 301, 302, 303, 307 - ActiveResource::Redirection 400 - ActiveResource::BadRequest 401 - ActiveResource::UnauthorizedAccess 403 - ActiveResource::ForbiddenAccess 404 - ActiveResource::ResourceNotFound 405 - ActiveResource::MethodNotAllowed 409 - ActiveResource::ResourceConflict 410 - ActiveResource::ResourceGone 422 - ActiveResource::ResourceInvalid (rescued by save as validation errors) 401..499 - ActiveResource::ClientError 500..599 - ActiveResource::ServerError Other - ActiveResource::ConnectionError Errors must be returned by the remote API in this format: { "errors": [ "fieldname1 message about fieldname1", "fieldname2 message about fieldname2" ] } Here is the code that parses these errors (active_resource/validations.rb): class Errors < ActiveModel::Errors def from_array(messages, save_cache = false) clear unless save_cache humanized_attributes = Hash[@base.attributes.keys.map { |attr_name| [attr_name.humanize, attr_name] }] 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 self[:base] << message if attr_message.nil? end end # Grabs errors from a json response. def from_json(json, save_cache = false) array = Array.wrap(ActiveSupport::JSON.decode(json)['errors']) rescue [] from_array array, save_cache end end