cloud_connect 2.0.2 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ require 'multi_json'
2
+
3
+ module CloudConnect
4
+ module Request
5
+ def delete(path, options={}, raw=false, force_urlencoded=false)
6
+ request(:delete, path, options, raw, force_urlencoded)
7
+ end
8
+
9
+ def get(path, options={}, raw=false, force_urlencoded=false)
10
+ request(:get, path, options, raw, force_urlencoded)
11
+ end
12
+
13
+ def patch(path, options={}, raw=false, force_urlencoded=false)
14
+ request(:patch, path, options, raw, force_urlencoded)
15
+ end
16
+
17
+ def post(path, options={}, raw=false, force_urlencoded=false)
18
+ request(:post, path, options, raw, force_urlencoded)
19
+ end
20
+
21
+ def put(path, options={}, raw=false, force_urlencoded=false)
22
+ request(:put, path, options, raw, force_urlencoded)
23
+ end
24
+
25
+ private
26
+
27
+ def request(method, path, options, raw, force_urlencoded)
28
+ path.sub(%r{^/}, '') # prevent leading slash
29
+ response = connection(raw, force_urlencoded).send(method) do |request|
30
+ request.headers['Accept'] = 'application/json'
31
+
32
+ case method
33
+ when :delete, :get
34
+ if auto_traversal && per_page.nil?
35
+ self.per_page = 100
36
+ end
37
+ options.merge!(:per_page => per_page) if per_page
38
+ request.url(path, options)
39
+ when :patch, :post, :put
40
+ request.path = path
41
+ if !force_urlencoded
42
+ request.body = MultiJson.dump(options) unless options.empty?
43
+ else
44
+ request.body = options unless options.empty?
45
+ end
46
+ puts request.inspect
47
+ end
48
+
49
+ request.headers['Host'] = CloudConnect.request_host if CloudConnect.request_host
50
+ end
51
+
52
+ if raw
53
+ response
54
+ elsif auto_traversal && ( next_url = links(response)["next"] )
55
+ response.body + request(method, next_url, options, raw, force_urlencoded)
56
+ else
57
+ response.body
58
+ end
59
+ end
60
+
61
+ def links(response)
62
+ links = ( response.headers["Link"] || "" ).split(', ').map do |link|
63
+ url, type = link.match(/<(.*?)>; rel="(\w+)"/).captures
64
+ [ type, url ]
65
+ end
66
+
67
+ Hash[ *links.flatten ]
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,3 @@
1
1
  module CloudConnect
2
- VERSION = "2.0.2"
2
+ VERSION = '3.0.3' unless defined?(CloudConnect::VERSION)
3
3
  end
data/lib/cloud_connect.rb CHANGED
@@ -1,43 +1,26 @@
1
- require 'faraday'
2
- require 'faraday_middleware'
3
- require 'forwardable'
4
-
5
- begin
6
- require 'yajl'
7
- MultiJson.engine = :yajl
8
- rescue LoadError
9
- require 'json'
10
- MultiJson.engine = :json_gem
11
- end
1
+ require 'cloud_connect/configuration'
2
+ require 'cloud_connect/client'
3
+ require 'cloud_connect/notification'
4
+ require 'cloud_connect/error'
12
5
 
13
6
  module CloudConnect
7
+ extend Configuration
14
8
  class << self
15
- attr_accessor :username
16
- attr_accessor :password
17
- attr_accessor :account
18
- attr_accessor :version
19
- attr_accessor :env
20
-
21
- def configure
22
- yield self
23
- true
9
+ # Alias for CloudConnect::Client.new
10
+ #
11
+ # @return [CloudConnect::Client]
12
+ def new(options={})
13
+ CloudConnect::Client.new(options)
24
14
  end
25
15
 
26
- require 'ext/object'
27
- require 'ext/module'
28
- require 'ext/hash'
29
-
30
- require 'faraday/cookie_auth'
31
- require 'faraday/raise_http_4xx'
32
- require 'faraday/raise_http_5xx'
16
+ # Delegate to CloudConnect::Client.new
17
+ def method_missing(method, *args, &block)
18
+ return super unless new.respond_to?(method)
19
+ new.send(method, *args, &block)
20
+ end
33
21
 
34
- require 'cloud_connect/error'
35
- require 'cloud_connect/client/units'
36
- require 'cloud_connect/client/users'
37
- require 'cloud_connect/client/messages'
38
- require 'cloud_connect/client/trackings'
39
- require 'cloud_connect/client/channels'
40
- require 'cloud_connect/client/fields'
41
- require 'cloud_connect/client'
22
+ def respond_to?(method, include_private=false)
23
+ new.respond_to?(method, include_private) || super(method, include_private)
24
+ end
42
25
  end
43
26
  end
@@ -0,0 +1,44 @@
1
+ require 'faraday'
2
+ require 'multi_json'
3
+
4
+ # @api private
5
+ module Faraday
6
+ class Response::RaiseCloudConnectError < Response::Middleware
7
+ def on_complete(response)
8
+ case response[:status].to_i
9
+ when 400
10
+ raise CloudConnect::BadRequest, error_message(response)
11
+ when 401
12
+ raise CloudConnect::Unauthorized, error_message(response)
13
+ when 403
14
+ raise CloudConnect::Forbidden, error_message(response)
15
+ when 404
16
+ raise CloudConnect::NotFound, error_message(response)
17
+ when 406
18
+ raise CloudConnect::NotAcceptable, error_message(response)
19
+ when 422
20
+ raise CloudConnect::UnprocessableEntity, error_message(response)
21
+ when 500
22
+ raise CloudConnect::InternalServerError, error_message(response)
23
+ when 501
24
+ raise CloudConnect::NotImplemented, error_message(response)
25
+ when 502
26
+ raise CloudConnect::BadGateway, error_message(response)
27
+ when 503
28
+ raise CloudConnect::ServiceUnavailable, error_message(response)
29
+ end
30
+ end
31
+
32
+ def error_message(response)
33
+ message = if (body = response[:body]) && !body.empty?
34
+ if body.is_a?(String)
35
+ body = MultiJson.load(body, :symbolize_keys => true)
36
+ end
37
+ " #{body[:title]}: #{body[:message]} Error(s): [#{body[:errors].join(", ")}]"
38
+ else
39
+ ''
40
+ end
41
+ "#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:status]}#{message}"
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloud_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 3.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,16 +9,16 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-22 00:00:00.000000000 Z
12
+ date: 2013-03-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: json
15
+ name: addressable
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 1.8.0
21
+ version: '2.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,15 +26,15 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 1.8.0
29
+ version: '2.2'
30
30
  - !ruby/object:Gem::Dependency
31
- name: multi_json
31
+ name: faraday
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: 1.10.0
37
+ version: '0.8'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,15 +42,15 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 1.10.0
45
+ version: '0.8'
46
46
  - !ruby/object:Gem::Dependency
47
- name: faraday
47
+ name: faraday_middleware
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 0.8.0
53
+ version: '0.8'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,15 +58,15 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 0.8.0
61
+ version: '0.8'
62
62
  - !ruby/object:Gem::Dependency
63
- name: faraday_middleware
63
+ name: hashie
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: 0.8.0
69
+ version: '1.2'
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,31 +74,47 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: 0.8.0
77
+ version: '1.2'
78
78
  - !ruby/object:Gem::Dependency
79
- name: hashie
79
+ name: multi_json
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
- - - ~>
83
+ - - ! '>='
84
84
  - !ruby/object:Gem::Version
85
- version: 1.2.0
85
+ version: '0'
86
86
  type: :runtime
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: json
96
+ requirement: !ruby/object:Gem::Requirement
89
97
  none: false
90
98
  requirements:
91
99
  - - ~>
92
100
  - !ruby/object:Gem::Version
93
- version: 1.2.0
101
+ version: '1.7'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '1.7'
94
110
  - !ruby/object:Gem::Dependency
95
- name: bundler
111
+ name: maruku
96
112
  requirement: !ruby/object:Gem::Requirement
97
113
  none: false
98
114
  requirements:
99
115
  - - ! '>='
100
116
  - !ruby/object:Gem::Version
101
- version: 1.0.0
117
+ version: '0'
102
118
  type: :development
103
119
  prerelease: false
104
120
  version_requirements: !ruby/object:Gem::Requirement
@@ -106,15 +122,15 @@ dependencies:
106
122
  requirements:
107
123
  - - ! '>='
108
124
  - !ruby/object:Gem::Version
109
- version: 1.0.0
125
+ version: '0'
110
126
  - !ruby/object:Gem::Dependency
111
- name: bluecloth
127
+ name: rake
112
128
  requirement: !ruby/object:Gem::Requirement
113
129
  none: false
114
130
  requirements:
115
131
  - - ! '>='
116
132
  - !ruby/object:Gem::Version
117
- version: '2.0'
133
+ version: '0'
118
134
  type: :development
119
135
  prerelease: false
120
136
  version_requirements: !ruby/object:Gem::Requirement
@@ -122,25 +138,57 @@ dependencies:
122
138
  requirements:
123
139
  - - ! '>='
124
140
  - !ruby/object:Gem::Version
125
- version: '2.0'
141
+ version: '0'
126
142
  - !ruby/object:Gem::Dependency
127
- name: rake
143
+ name: rspec
128
144
  requirement: !ruby/object:Gem::Requirement
129
145
  none: false
130
146
  requirements:
131
- - - ~>
147
+ - - ! '>='
132
148
  - !ruby/object:Gem::Version
133
- version: '0.8'
149
+ version: '0'
134
150
  type: :development
135
151
  prerelease: false
136
152
  version_requirements: !ruby/object:Gem::Requirement
137
153
  none: false
138
154
  requirements:
139
- - - ~>
155
+ - - ! '>='
140
156
  - !ruby/object:Gem::Version
141
- version: '0.8'
157
+ version: '0'
142
158
  - !ruby/object:Gem::Dependency
143
- name: rspec
159
+ name: simplecov
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: webmock
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ - !ruby/object:Gem::Dependency
191
+ name: yard
144
192
  requirement: !ruby/object:Gem::Requirement
145
193
  none: false
146
194
  requirements:
@@ -155,38 +203,38 @@ dependencies:
155
203
  - - ! '>='
156
204
  - !ruby/object:Gem::Version
157
205
  version: '0'
158
- description: Ruby Wrapper for the Mobile Devices Cloud Connect API
206
+ description: Simple wrapper for the CloudConnect v3 API
159
207
  email:
160
- - alexandre.mora@mobile-devices.fr
208
+ - jean-paul.bonnetouche@mobile-devices.fr
161
209
  executables: []
162
210
  extensions: []
163
211
  extra_rdoc_files: []
164
212
  files:
165
213
  - .gitignore
166
- - .yardopts
167
214
  - Gemfile
168
215
  - Gemfile.lock
169
- - HISTORY.md
170
216
  - README.md
171
217
  - Rakefile
172
218
  - cloud_connect.gemspec
173
219
  - lib/cloud_connect.rb
220
+ - lib/cloud_connect/authentication.rb
174
221
  - lib/cloud_connect/client.rb
222
+ - lib/cloud_connect/client/assets.rb
175
223
  - lib/cloud_connect/client/channels.rb
224
+ - lib/cloud_connect/client/configurations.rb
225
+ - lib/cloud_connect/client/custom_methods.rb
176
226
  - lib/cloud_connect/client/fields.rb
177
227
  - lib/cloud_connect/client/messages.rb
178
- - lib/cloud_connect/client/trackings.rb
179
- - lib/cloud_connect/client/units.rb
180
- - lib/cloud_connect/client/users.rb
228
+ - lib/cloud_connect/client/tracks.rb
229
+ - lib/cloud_connect/configuration.rb
230
+ - lib/cloud_connect/connection.rb
181
231
  - lib/cloud_connect/error.rb
232
+ - lib/cloud_connect/notification.rb
233
+ - lib/cloud_connect/notification/notification.rb
234
+ - lib/cloud_connect/request.rb
182
235
  - lib/cloud_connect/version.rb
183
- - lib/ext/hash.rb
184
- - lib/ext/module.rb
185
- - lib/ext/object.rb
186
- - lib/faraday/cookie_auth.rb
187
- - lib/faraday/raise_http_4xx.rb
188
- - lib/faraday/raise_http_5xx.rb
189
- homepage: http://rubygems.org/gems/cloud_connect
236
+ - lib/faraday/response/raise_cloud_connect_error.rb
237
+ homepage: https://github.com/mobile-devices/cloud_connect
190
238
  licenses: []
191
239
  post_install_message:
192
240
  rdoc_options: []
@@ -209,6 +257,6 @@ rubyforge_project:
209
257
  rubygems_version: 1.8.23
210
258
  signing_key:
211
259
  specification_version: 3
212
- summary: Wrapper for Cloud Connect
260
+ summary: Wrapper for the CloudConnect v3 API
213
261
  test_files: []
214
262
  has_rdoc:
data/.yardopts DELETED
@@ -1,7 +0,0 @@
1
- 'lib/cloud_connect.rb' 'lib/cloud_connect/**/*.rb'
2
- --no-private
3
- --protected
4
- --tag format:"Supported formats"
5
- --tag authenticated:"Requires Authentication"
6
- --tag rate_limited:"Rate Limited"
7
- --markup markdown
data/HISTORY.md DELETED
@@ -1,33 +0,0 @@
1
- 2.0.2 - August 22, 2014
2
- -----------------------
3
- * Add support for old school APIs (v1.5)
4
-
5
- 2.0.1 - August 13, 2014
6
- -----------------------
7
- * Update faraday from 0.5.1 to 0.8.9
8
- * Update faraday_middleware from 0.1.7 to 0.8.8
9
- * Update multi_json from 0.0.5 to 1.10.1
10
- * Update hashie from 0.4.0 to 1.2.0
11
-
12
- 2.0.0 - December 6, 2011
13
- ------------------------
14
- * Release current version as 2.0.0 (Synchronise with CloudConnect v2) for reference before "branching" for 3.0.0 (CloudConnect v3),
15
- to ease integration and documentation.
16
-
17
- 0.0.2 - March 22, 2011
18
- ----------------------
19
- * [Removed HTTP status debug log](https://github.com/mobile-devices/cloud_connect/commit/1d032259d16b82749fe595bfa0a15f05bb8af65a) ([@dohzya][http://twitter.com/#!/dohzya])
20
- * [Fixed bad links in README](https://github.com/mobile-devices/cloud_connect/commit/326416c0dcc3e444f6bb4cefbd5a63d83f2e5aa0)
21
-
22
- 0.0.1 - February 16, 2011
23
- -------------------------
24
- * Initial release
25
-
26
- Thanks to the following people for making this possible
27
- -------------------------------------------------------
28
- - John Nunemaker ([@jnunemaker](http://twitter.com/#!/jnunemaker))
29
- for the twitter gem that inspired this one.
30
- - Rick Olson ([@technoweenie](https://github.com/technoweenie))
31
- for the faraday gem
32
- - Wynn Netherland ([@pengwynn](http://github.com/pengwynn))
33
- for the faraday_middleware gem
@@ -1,22 +0,0 @@
1
- module CloudConnect
2
- module Trackings
3
-
4
- # Retrieve list of tracking data
5
- #
6
- # @see http://develop.g8teway.com/p/tracking_records.html#listing_tracking_records
7
- # @param [Hash] opts the options to filter the tracking data.
8
- # @options opts [String] :ret Select attributes to fetch
9
- # @options opts [String] :userids List of unit ids
10
- # @options opts [String] :fieldids List of field ids
11
- # @options opts [Integer] :from Minimum ID
12
- # @options opts [Integer] :to Maximum ID
13
- # @options opts [Integer] :id_min Minimum ID
14
- # @options opts [Integer] :id_max Maximum ID
15
- # @options opts [Integer] :limit Number of elements to fetch (default 25
16
- # @return [Array of Hashie::Mash] Tracking data
17
- def trackings(opts = {})
18
- trackings = connection.get(connection.build_url("tracking_records", opts)).body
19
- trackings.map!{|hash| hash.values.first}
20
- end
21
- end
22
- end
@@ -1,77 +0,0 @@
1
- module CloudConnect
2
- module Units
3
-
4
- # Returns all units that match parameters provided in +opts+ list
5
- # (if +opts+ is provided)
6
- #
7
- # @param [Hash] opts the options to filter the units.
8
- # @option opts [String] :ret ('id, lat, long, time') Select attributes to fetch
9
- # @option opts [String] :unitids List of unit ids
10
- # @option opts [String] :fieldids List of field ids
11
- # @option opts [String] :unknow Allow unknown position
12
- # @option opts [Integer] :id_min Minimum ID
13
- # @option opts [Integer] :id_max Maximum ID
14
- # @option opts [Integer] :limit Number of elements to fetch (default 25
15
- # @return [Array<Hashie::Mash>] Units
16
- # @see http://develop.g8teway.com/p/units.html#listing_units
17
- def units(opts = {})
18
- units = connection.get(connection.build_url("units", opts)).body
19
- units.map!{|hash| hash.values.first}
20
- units.each{|u| u.extend UnitMethods; u._cloud_connect = self;}
21
- end
22
-
23
- # Search for a specific unit knowing it's modid
24
- #
25
- # @param [String] modids the comma separated list modids.
26
- # Partial modids can be provided using the '*' caracter
27
- # @example
28
- # find_unit("*3216*")
29
- # @return [Array<Hashie::Mash>] Unit
30
- # @see http://develop.g8teway.com/p/units.html#searching_units
31
- def find_units(modids)
32
- # TODO: Rename unit_search?
33
- units = connection.get(connection.build_url("units/search", :modids => modids)).body
34
- units.map!{|hash| hash.values.first}
35
- units.each{|u| u.extend UnitMethods; u._cloud_connect = self;}
36
- end
37
-
38
- # Return information about a specific unit
39
- #
40
- # @param [String] unit_id Unit ID
41
- # @param [Hash] opts the options to filter the units.
42
- # @option opts [String] :ret ('id, lat, long, time') Select attributes to fetch
43
- # @option opts [String] :fieldids List of field ids
44
- # @option opts [String] :unknow Allow unknown position
45
- # @return [Hashie::Mash] Unit info
46
- def unit(unit_id=nil, opts = {})
47
- units = connection.get(connection.build_url("units", opts.merge(:unitids => unit_id))).body
48
- units.map!{|hash| hash.values.first}
49
- units.each{|u| u.extend UnitMethods; u._cloud_connect = self;}
50
- units.first
51
- end
52
-
53
- module UnitMethods
54
- # @private
55
- attr_accessor :_cloud_connect
56
-
57
- # Return the last known location of a specific unit
58
- #
59
- # @return [Integer lat, Integer long] Latitude, Longitude
60
- def location
61
- [lat.to_f / 100_000, lng.to_f / 100_000]
62
- end
63
-
64
- # Send a message to the unit
65
- #
66
- # @param [Integer] channel
67
- # @param [String] content
68
- # @param [Hash] opts
69
- # @return [Hashie::Mash] The message
70
- # @see http://develop.g8teway.com/p/messages.html#sending_a_new_message
71
- def send_message(channel, content, opts = {})
72
- raise "Unknown unit id, try providing :ret => 'id' when fetching units from the API." unless id && id > 0
73
- _cloud_connect.send_message(id, channel, content, opts)
74
- end
75
- end
76
- end
77
- end
@@ -1,36 +0,0 @@
1
- module CloudConnect
2
- module Users
3
-
4
- # Retrieve list of users
5
- #
6
- # @see http://develop.g8teway.com/p/users.html#searching_and_listing_users
7
- # @param [Hash] opts the options to filter the units.
8
- # @options opts [String] :ret Select attributes to fetch
9
- # @options opts [String] :userids List of unit ids
10
- # @options opts [String] :logins List of field ids
11
- # @options opts [Integer] :id_min Minimum ID
12
- # @options opts [Integer] :id_max Maximum ID
13
- # @options opts [Integer] :limit Number of elements to fetch (default 25
14
- # @return [Array of Hashie::Mash] Users
15
- def users(opts = {})
16
- opts.default! :ret => %w(id login email).join(',')
17
- users = connection.get(connection.build_url('users', opts)).body
18
- users.map!{|hash| hash.values.first}
19
- end
20
-
21
- # Return information about a specific user
22
- #
23
- # @param [String] user_id Unit ID
24
- # @return [Hashie::Mash] User info
25
- def user(user_id = nil)
26
- user_id = username if user_id.nil? || user_id == ""
27
- if user_id.to_i.to_s == user_id.to_s
28
- users = connection.get(connection.build_url('users', :userids => user_id)).body
29
- else
30
- users = connection.get(connection.build_url('users', :logins => user_id)).body
31
- end
32
- users.map!{|hash| hash.values.first}
33
- users.first
34
- end
35
- end
36
- end
data/lib/ext/hash.rb DELETED
@@ -1,5 +0,0 @@
1
- class Hash
2
- def default!(other_hash)
3
- merge!( other_hash ){|k,o,n| o }
4
- end
5
- end