harpy 1.0.0 → 2.0.0.preview1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.forgejo/workflows/test.yml +33 -0
- data/.github/workflows/test.yml +20 -0
- data/.gitignore +2 -1
- data/README.md +8 -9
- data/harpy.gemspec +8 -5
- data/lib/harpy/client.rb +51 -13
- data/lib/harpy/entry_point.rb +3 -3
- data/lib/harpy/gem_version.rb +14 -0
- data/lib/harpy/resource.rb +113 -96
- data/lib/harpy/version.rb +9 -0
- data/lib/harpy.rb +3 -2
- data/spec/harpy/client_spec.rb +85 -36
- data/spec/harpy/entry_point_spec.rb +19 -19
- data/spec/harpy/resource_spec.rb +254 -255
- data/spec/harpy_spec.rb +20 -20
- data/spec/spec_helper.rb +31 -2
- metadata +63 -51
- data/.travis.yml +0 -9
- data/Gemfile.lock +0 -56
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c6bccc44b8e3516964d14dfb259eb7b9294c42449c4f9f72876b5ed1852ed3d0
|
|
4
|
+
data.tar.gz: 989d3494a0b11a5ee04b2c472c2f3ac85920bf42296c3194c1a756f7e1ddd680
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c0d99509101d673e64f08a18d7dd0ac8335f59e462e60e51638e365fc54b5a11bb5cd43e1454052af17bab69ebb7a94b6b69dbd0de27a5d8932f694a90e61c5b
|
|
7
|
+
data.tar.gz: 83f63ada339c06bd86231d8175b767bf5e56afffd80d7862093189a28e2eb4c86cdf8243b5cd88113fca49715f8f6a94bda439983c024cbef383a171a5ee48d3
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: docker
|
|
10
|
+
container:
|
|
11
|
+
image: docker.io/library/ruby:${{ matrix.image }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
include:
|
|
16
|
+
- ruby: "3.4"
|
|
17
|
+
image: "3.4"
|
|
18
|
+
- ruby: "4.0"
|
|
19
|
+
image: "4.0"
|
|
20
|
+
- ruby: "4.1"
|
|
21
|
+
image: "4.1-rc"
|
|
22
|
+
steps:
|
|
23
|
+
- name: Install Node.js 24 for the checkout action
|
|
24
|
+
run: |
|
|
25
|
+
apt-get update
|
|
26
|
+
apt-get install -y ca-certificates curl
|
|
27
|
+
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
|
|
28
|
+
apt-get install -y nodejs
|
|
29
|
+
node --version
|
|
30
|
+
- name: Check out the repository
|
|
31
|
+
uses: actions/checkout@v7
|
|
32
|
+
- run: bundle install
|
|
33
|
+
- run: bundle exec rake
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
fail-fast: false
|
|
12
|
+
matrix:
|
|
13
|
+
ruby: ["3.4", "4.0", "4.1"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: ruby/setup-ruby@v1
|
|
17
|
+
with:
|
|
18
|
+
ruby-version: ${{ matrix.ruby }}
|
|
19
|
+
bundler-cache: true
|
|
20
|
+
- run: bundle exec rake
|
data/.gitignore
CHANGED
data/README.md
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
Harpy
|
|
2
2
|
======
|
|
3
3
|
|
|
4
|
-
[](https://codeclimate.com/github/TalentBox/harpy)
|
|
4
|
+
[](https://github.com/TalentBox/harpy/actions/workflows/test.yml)
|
|
6
5
|
|
|
7
6
|
Client for REST API with HATEOAS
|
|
8
7
|
|
|
9
8
|
Dependencies
|
|
10
9
|
------------
|
|
11
10
|
|
|
12
|
-
* Ruby
|
|
13
|
-
* gem "
|
|
14
|
-
* gem "activesupport", ">=
|
|
15
|
-
* gem "activemodel", ">=
|
|
16
|
-
* gem "hash-deep-merge", "
|
|
11
|
+
* Ruby >= 3.4.
|
|
12
|
+
* gem "httpx", ">= 1.0"
|
|
13
|
+
* gem "activesupport", ">= 5.2.0"
|
|
14
|
+
* gem "activemodel", ">= 5.2.0"
|
|
15
|
+
* gem "hash-deep-merge", ">= 0.1.1"
|
|
17
16
|
|
|
18
17
|
Usage
|
|
19
18
|
-----
|
|
@@ -44,7 +43,7 @@ Usage
|
|
|
44
43
|
# => instance of MyModel with attributes filled in on 200
|
|
45
44
|
# => nil on 404
|
|
46
45
|
# => raises Harpy::ClientTimeout on timeout
|
|
47
|
-
# => raises Harpy::ClientError on
|
|
46
|
+
# => raises Harpy::ClientError on HTTP client error
|
|
48
47
|
# => raises Harpy::InvalidResponseCode on other response codes
|
|
49
48
|
|
|
50
49
|
# Fetch multiple by url in parallel
|
|
@@ -60,7 +59,7 @@ Usage
|
|
|
60
59
|
}
|
|
61
60
|
# => return an array of MyModel instances on 200
|
|
62
61
|
# => raises Harpy::ClientTimeout on timeout
|
|
63
|
-
# => raises Harpy::ClientError on
|
|
62
|
+
# => raises Harpy::ClientError on HTTP client error
|
|
64
63
|
# => raises Harpy::InvalidResponseCode on other response codes
|
|
65
64
|
|
|
66
65
|
# Search by first_name
|
data/harpy.gemspec
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "harpy"
|
|
3
4
|
|
|
4
5
|
Gem::Specification.new do |s|
|
|
5
6
|
s.name = "harpy"
|
|
6
|
-
s.version =
|
|
7
|
+
s.version = Harpy::VERSION::STRING
|
|
7
8
|
s.platform = Gem::Platform::RUBY
|
|
8
9
|
s.authors = ["Joseph HALTER", "Jonathan TRON"]
|
|
9
10
|
s.email = ["joseph.halter@thetalentbox.com", "jonathan.tron@thetalentbox.com"]
|
|
@@ -11,17 +12,19 @@ Gem::Specification.new do |s|
|
|
|
11
12
|
s.summary = %q{Client for REST API}
|
|
12
13
|
s.description = %q{Client for REST API with HATEOAS}
|
|
13
14
|
s.license = "MIT"
|
|
15
|
+
s.required_ruby_version = ">= 3.4"
|
|
14
16
|
|
|
15
17
|
s.files = `git ls-files`.split("\n")
|
|
16
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
17
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
18
20
|
s.require_paths = ["lib"]
|
|
19
21
|
|
|
20
|
-
s.add_runtime_dependency "
|
|
21
|
-
s.add_runtime_dependency "activesupport", [">=
|
|
22
|
-
s.add_runtime_dependency "activemodel", [">=
|
|
23
|
-
s.add_runtime_dependency "hash-deep-merge", ["
|
|
22
|
+
s.add_runtime_dependency "httpx", ">= 1.0"
|
|
23
|
+
s.add_runtime_dependency "activesupport", [">= 5.2.0"]
|
|
24
|
+
s.add_runtime_dependency "activemodel", [">= 5.2.0"]
|
|
25
|
+
s.add_runtime_dependency "hash-deep-merge", [">= 0.1.1"]
|
|
24
26
|
|
|
25
27
|
s.add_development_dependency "rake", [">= 0.8.7"]
|
|
26
28
|
s.add_development_dependency "rspec"
|
|
29
|
+
s.add_development_dependency "webmock"
|
|
27
30
|
end
|
data/lib/harpy/client.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "base64"
|
|
2
|
+
require "openssl"
|
|
3
|
+
require "httpx"
|
|
2
4
|
require "hash_deep_merge"
|
|
3
5
|
|
|
4
6
|
module Harpy
|
|
@@ -7,6 +9,7 @@ module Harpy
|
|
|
7
9
|
|
|
8
10
|
def initialize(opts=nil)
|
|
9
11
|
self.options = (opts || {})
|
|
12
|
+
@session = HTTPX::Session.new
|
|
10
13
|
end
|
|
11
14
|
|
|
12
15
|
def get(url_or_urls, opts=nil)
|
|
@@ -34,33 +37,68 @@ module Harpy
|
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def run(requests)
|
|
37
|
-
requests.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
return [] if requests.empty?
|
|
41
|
+
|
|
42
|
+
responses = @session.request(*requests)
|
|
43
|
+
responses.is_a?(Array) ? responses : [responses]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def response_status(response)
|
|
47
|
+
response.is_a?(HTTPX::ErrorResponse) ? 0 : response.status
|
|
40
48
|
end
|
|
41
49
|
|
|
42
50
|
def invalid_code(response)
|
|
43
|
-
if response.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
if response.is_a?(HTTPX::ErrorResponse)
|
|
52
|
+
if response.error.is_a?(HTTPX::TimeoutError)
|
|
53
|
+
raise ClientTimeout
|
|
54
|
+
else
|
|
55
|
+
raise ClientError, response.error.message
|
|
56
|
+
end
|
|
47
57
|
else
|
|
48
|
-
raise InvalidResponseCode, response.
|
|
58
|
+
raise InvalidResponseCode, response.status.to_s
|
|
49
59
|
end
|
|
50
60
|
end
|
|
51
61
|
|
|
52
62
|
private
|
|
53
63
|
|
|
54
64
|
def request(method, urls, opts=nil)
|
|
55
|
-
opts = options.deep_merge(opts || {})
|
|
65
|
+
opts = httpx_options(options.deep_merge(opts || {}))
|
|
56
66
|
case urls
|
|
57
67
|
when Array
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
urls.collect do |url|
|
|
69
|
+
@session.build_request(method, url, opts.dup)
|
|
60
70
|
end
|
|
61
71
|
else
|
|
62
|
-
|
|
72
|
+
@session.request(method.to_s.upcase, urls, **opts)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def httpx_options(opts)
|
|
77
|
+
timeout = opts[:timeout]
|
|
78
|
+
if timeout.is_a?(Numeric)
|
|
79
|
+
opts[:timeout] = {total_request_timeout: timeout.to_f / 1000} if timeout.positive?
|
|
80
|
+
opts.delete(:timeout) unless timeout.positive?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
ssl_options = (opts[:ssl] || {}).dup
|
|
84
|
+
if opts.key?(:ssl_verifypeer)
|
|
85
|
+
verify_peer = opts.delete(:ssl_verifypeer)
|
|
86
|
+
ssl_options[:verify_mode] = verify_peer ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
|
87
|
+
end
|
|
88
|
+
if opts.key?(:ssl_verifyhost)
|
|
89
|
+
verify_host = opts.delete(:ssl_verifyhost)
|
|
90
|
+
ssl_options[:verify_hostname] = verify_host != false && verify_host != 0
|
|
91
|
+
end
|
|
92
|
+
opts[:ssl] = ssl_options unless ssl_options.empty?
|
|
93
|
+
|
|
94
|
+
username = opts.delete(:username)
|
|
95
|
+
password = opts.delete(:password)
|
|
96
|
+
if username || password
|
|
97
|
+
headers = (opts[:headers] || {}).dup
|
|
98
|
+
headers["Authorization"] ||= "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
|
|
99
|
+
opts[:headers] = headers
|
|
63
100
|
end
|
|
101
|
+
opts
|
|
64
102
|
end
|
|
65
103
|
end
|
|
66
104
|
end
|
data/lib/harpy/entry_point.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Harpy
|
|
|
10
10
|
|
|
11
11
|
def resource_url(resource_type)
|
|
12
12
|
response = Harpy.client.get url
|
|
13
|
-
case response
|
|
13
|
+
case Harpy.client.response_status(response)
|
|
14
14
|
when 200
|
|
15
15
|
body = JSON.parse response.body
|
|
16
16
|
link = (body["link"] || []).detect{|link| link["rel"] == resource_type}
|
|
@@ -22,9 +22,9 @@ module Harpy
|
|
|
22
22
|
|
|
23
23
|
def urn(urn)
|
|
24
24
|
response = Harpy.client.get "#{url}/#{urn}"
|
|
25
|
-
case response
|
|
25
|
+
case Harpy.client.response_status(response)
|
|
26
26
|
when 301
|
|
27
|
-
response.
|
|
27
|
+
response.headers["location"]
|
|
28
28
|
when 404
|
|
29
29
|
nil
|
|
30
30
|
else
|
data/lib/harpy/resource.rb
CHANGED
|
@@ -16,6 +16,7 @@ module Harpy
|
|
|
16
16
|
base.send :include, ActiveModel::Validations
|
|
17
17
|
base.send :include, ActiveModel::Validations::Callbacks
|
|
18
18
|
base.define_model_callbacks :save, :create, :update, :destroy, :only => [:before, :after]
|
|
19
|
+
base.send :include, InstanceMethods
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def self.from_url(hash)
|
|
@@ -61,7 +62,7 @@ module Harpy
|
|
|
61
62
|
|
|
62
63
|
def search(conditions={})
|
|
63
64
|
response = Harpy.client.get url, :params => conditions
|
|
64
|
-
case response
|
|
65
|
+
case Harpy.client.response_status(response)
|
|
65
66
|
when 200
|
|
66
67
|
parsed = JSON.parse response.body
|
|
67
68
|
items = parsed[resource_name].collect{|model| new model}
|
|
@@ -93,6 +94,14 @@ module Harpy
|
|
|
93
94
|
delete_from_urn urn id
|
|
94
95
|
end
|
|
95
96
|
|
|
97
|
+
def uman_attribute_name(attr, options = {})
|
|
98
|
+
attr
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def lookup_ancestors
|
|
102
|
+
[self]
|
|
103
|
+
end
|
|
104
|
+
|
|
96
105
|
private
|
|
97
106
|
|
|
98
107
|
def url
|
|
@@ -100,7 +109,7 @@ module Harpy
|
|
|
100
109
|
end
|
|
101
110
|
|
|
102
111
|
def from_url_handler(response)
|
|
103
|
-
case response
|
|
112
|
+
case Harpy.client.response_status(response)
|
|
104
113
|
when 200
|
|
105
114
|
new JSON.parse response.body
|
|
106
115
|
when 404
|
|
@@ -111,7 +120,7 @@ module Harpy
|
|
|
111
120
|
end
|
|
112
121
|
|
|
113
122
|
def delete_from_url_handler(response)
|
|
114
|
-
case response
|
|
123
|
+
case Harpy.client.response_status(response)
|
|
115
124
|
when 204
|
|
116
125
|
true
|
|
117
126
|
when 404
|
|
@@ -122,128 +131,136 @@ module Harpy
|
|
|
122
131
|
end
|
|
123
132
|
end
|
|
124
133
|
|
|
125
|
-
|
|
126
|
-
@attrs = {}
|
|
127
|
-
self.attributes = attrs || {}
|
|
128
|
-
end
|
|
134
|
+
module InstanceMethods
|
|
129
135
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
def initialize(attrs = nil)
|
|
137
|
+
@attrs = {}
|
|
138
|
+
self.attributes = attrs || {}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def attributes=(attrs)
|
|
142
|
+
attrs.each do |key, value|
|
|
143
|
+
if respond_to? "#{key}="
|
|
144
|
+
send "#{key}=", value
|
|
145
|
+
else
|
|
146
|
+
@attrs[key] = value
|
|
147
|
+
end
|
|
136
148
|
end
|
|
137
149
|
end
|
|
138
|
-
end
|
|
139
150
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
def as_json(*args)
|
|
152
|
+
hash = @attrs.dup
|
|
153
|
+
hash.delete "link"
|
|
154
|
+
hash.delete "urn"
|
|
155
|
+
hash
|
|
156
|
+
end
|
|
146
157
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
def save
|
|
159
|
+
if valid?
|
|
160
|
+
run_callbacks :save do
|
|
161
|
+
json = JSON.generate as_json
|
|
162
|
+
raise BodyToBig, "Size: #{json.bytesize} bytes (max 1MB)" if json.bytesize > 1.megabyte
|
|
163
|
+
persisted? ? update(json) : create(json)
|
|
164
|
+
end
|
|
165
|
+
else
|
|
166
|
+
false
|
|
153
167
|
end
|
|
154
|
-
else
|
|
155
|
-
false
|
|
156
168
|
end
|
|
157
|
-
end
|
|
158
169
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
def destroy
|
|
171
|
+
raise Harpy::UrlRequired unless url
|
|
172
|
+
run_callbacks :destroy do
|
|
173
|
+
process_response Harpy.client.delete(url), :destroy
|
|
174
|
+
end
|
|
163
175
|
end
|
|
164
|
-
end
|
|
165
176
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
177
|
+
def link(rel)
|
|
178
|
+
link = (@attrs["link"]||[]).detect{|l| l["rel"]==rel.to_s}
|
|
179
|
+
link["href"] if link
|
|
180
|
+
end
|
|
170
181
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
def url
|
|
183
|
+
link "self"
|
|
184
|
+
end
|
|
174
185
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
186
|
+
def url_collection
|
|
187
|
+
Harpy.entry_point.resource_url self.class.resource_name
|
|
188
|
+
end
|
|
178
189
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
190
|
+
def id
|
|
191
|
+
@attrs["urn"].split(":").last if @attrs["urn"]
|
|
192
|
+
end
|
|
182
193
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
194
|
+
def persisted?
|
|
195
|
+
@attrs["urn"].present?
|
|
196
|
+
end
|
|
186
197
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
198
|
+
def inspect
|
|
199
|
+
"<#{self.class.name} @attrs:#{@attrs.inspect} @errors:#{errors.full_messages.inspect} persisted:#{persisted?}>"
|
|
200
|
+
end
|
|
190
201
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
def has_key?(key)
|
|
203
|
+
@attrs.has_key? key.to_s
|
|
204
|
+
end
|
|
194
205
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
def hash
|
|
207
|
+
urn.hash
|
|
208
|
+
end
|
|
198
209
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
210
|
+
def ==(other)
|
|
211
|
+
other.equal?(self) || (urn && other.instance_of?(self.class) && other.urn == urn)
|
|
212
|
+
end
|
|
213
|
+
alias_method :eql?, :==
|
|
203
214
|
|
|
204
|
-
|
|
215
|
+
private
|
|
205
216
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
217
|
+
def create(json)
|
|
218
|
+
run_callbacks :create do
|
|
219
|
+
process_response Harpy.client.post(url_collection, :body => json), :create
|
|
220
|
+
end
|
|
209
221
|
end
|
|
210
|
-
end
|
|
211
222
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
223
|
+
def update(json)
|
|
224
|
+
run_callbacks :update do
|
|
225
|
+
raise Harpy::UrlRequired unless url
|
|
226
|
+
process_response Harpy.client.put(url, :body => json), :update
|
|
227
|
+
end
|
|
216
228
|
end
|
|
217
|
-
end
|
|
218
229
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
230
|
+
def process_response(response, context)
|
|
231
|
+
case Harpy.client.response_status(response)
|
|
232
|
+
when 200, 201, 302
|
|
233
|
+
@attrs.merge! JSON.parse(response.body)
|
|
234
|
+
true
|
|
235
|
+
when 204
|
|
236
|
+
context==:create ? Harpy.client.invalid_code(response) : true
|
|
237
|
+
when 401
|
|
238
|
+
raise Harpy::Unauthorized, "Server returned a 401 response code"
|
|
239
|
+
when 422
|
|
240
|
+
JSON.parse(response.body)["errors"].each do |attr, attr_errors|
|
|
241
|
+
attr_errors.each{|attr_error| errors.add(attr, :invalid, message: attr_error) }
|
|
242
|
+
end
|
|
243
|
+
false
|
|
244
|
+
else
|
|
245
|
+
Harpy.client.invalid_code response
|
|
231
246
|
end
|
|
232
|
-
false
|
|
233
|
-
else
|
|
234
|
-
Harpy.client.invalid_code response
|
|
235
247
|
end
|
|
236
|
-
end
|
|
237
248
|
|
|
238
|
-
|
|
239
|
-
key = method.to_s
|
|
240
|
-
if persisted? && !@attrs.has_key?(key)
|
|
241
|
-
super
|
|
242
|
-
elsif key=~/[\]=]\z/
|
|
243
|
-
super
|
|
244
|
-
else
|
|
249
|
+
def read_attribute_for_validation(key)
|
|
245
250
|
@attrs[key]
|
|
246
251
|
end
|
|
252
|
+
public :read_attribute_for_validation
|
|
253
|
+
|
|
254
|
+
def method_missing(method, *args)
|
|
255
|
+
key = method.to_s
|
|
256
|
+
if persisted? && !@attrs.has_key?(key)
|
|
257
|
+
super
|
|
258
|
+
elsif key=~/[\]=]\z/
|
|
259
|
+
super
|
|
260
|
+
else
|
|
261
|
+
@attrs[key]
|
|
262
|
+
end
|
|
263
|
+
end
|
|
247
264
|
end
|
|
248
265
|
end
|
|
249
266
|
end
|
data/lib/harpy.rb
CHANGED
|
@@ -14,6 +14,7 @@ module Harpy
|
|
|
14
14
|
autoload :Resource, "harpy/resource"
|
|
15
15
|
autoload :BodyToBig, "harpy/resource"
|
|
16
16
|
autoload :UnknownResponseCode, "harpy/resource"
|
|
17
|
+
autoload :VERSION, "harpy/gem_version"
|
|
17
18
|
|
|
18
19
|
def self.client=(new_client)
|
|
19
20
|
@client = new_client
|
|
@@ -38,10 +39,10 @@ module Harpy
|
|
|
38
39
|
def self.entry_point
|
|
39
40
|
@entry_point || raise(EntryPointRequired, 'you can setup one with Harpy.entry_point_url = "http://localhost"')
|
|
40
41
|
end
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
def self.reset
|
|
43
44
|
@client = nil
|
|
44
45
|
@entry_point = nil
|
|
45
46
|
end
|
|
46
47
|
|
|
47
|
-
end
|
|
48
|
+
end
|