initial commit.
[reserve_usernames.git] / README.md
1 Reserve Usernames
2 ==============================
3
4 This is an engine that adds support to leap_web for checking an external REST
5 API to see if a username is available. Once the account is created, the
6 username is reserved via the same external API.
7
8 TODO:
9
10 * support the ability for a user to change their username
11 * sanitize error messages before displaying
12
13 See the file config.yml for the development and production values used for
14 accessing the remote API.
15
16 This gem is distributed on the same license as leap_web.
17
18 Notes
19 --------------------------------
20
21 This engine uses ActiveResource, which maps a ActiveRecord-like interface to a
22 REST API. So, the remote API must conform to the API expected by
23 ActiveResource.
24
25 * http://rubydoc.info/gems/activeresource/3.2.18/frames
26 * http://api.rubyonrails.org/v3.2.18/files/activeresource/README_rdoc.html
27 * https://github.com/rails/activeresource
28
29 ActiveResource exceptions:
30
31     301, 302, 303, 307 - ActiveResource::Redirection
32     400 - ActiveResource::BadRequest
33     401 - ActiveResource::UnauthorizedAccess
34     403 - ActiveResource::ForbiddenAccess
35     404 - ActiveResource::ResourceNotFound
36     405 - ActiveResource::MethodNotAllowed
37     409 - ActiveResource::ResourceConflict
38     410 - ActiveResource::ResourceGone
39     422 - ActiveResource::ResourceInvalid (rescued by save as validation errors)
40     401..499 - ActiveResource::ClientError
41     500..599 - ActiveResource::ServerError
42     Other - ActiveResource::ConnectionError
43
44 Errors must be returned by the remote API in this format:
45
46     {
47       "errors": [
48          "fieldname1 message about fieldname1",
49          "fieldname2 message about fieldname2"
50       ]
51     }
52
53 Here is the code that parses these errors (active_resource/validations.rb):
54
55     class Errors < ActiveModel::Errors
56       def from_array(messages, save_cache = false)
57         clear unless save_cache
58         humanized_attributes = Hash[@base.attributes.keys.map { |attr_name| [attr_name.humanize, attr_name] }]
59         messages.each do |message|
60           attr_message = humanized_attributes.keys.detect do |attr_name|
61             if message[0, attr_name.size + 1] == "#{attr_name} "
62               add humanized_attributes[attr_name], message[(attr_name.size + 1)..-1]
63             end
64           end
65
66           self[:base] << message if attr_message.nil?
67         end
68       end
69
70       # Grabs errors from a json response.
71       def from_json(json, save_cache = false)
72         array = Array.wrap(ActiveSupport::JSON.decode(json)['errors']) rescue []
73         from_array array, save_cache
74       end
75     end