her 0.6.7 → 0.6.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -4
- data/README.md +20 -0
- data/gemfiles/Gemfile.activemodel-3.2.x +5 -0
- data/gemfiles/Gemfile.activemodel-4.0 +5 -0
- data/lib/her/model/associations/association.rb +16 -0
- data/lib/her/model/attributes.rb +1 -1
- data/lib/her/model/http.rb +1 -1
- data/lib/her/model/orm.rb +1 -1
- data/lib/her/model/parse.rb +40 -2
- data/lib/her/version.rb +1 -1
- data/spec/model/associations_spec.rb +6 -0
- data/spec/model/parse_spec.rb +44 -0
- data/spec/model/paths_spec.rb +22 -0
- metadata +6 -5
- data/gemfiles/activemodel-4.0.gemfile +0 -5
data/.travis.yml
CHANGED
@@ -7,14 +7,14 @@ rvm:
|
|
7
7
|
- 1.8.7
|
8
8
|
|
9
9
|
gemfile:
|
10
|
-
- Gemfile
|
11
|
-
- gemfiles/activemodel-
|
10
|
+
- gemfiles/Gemfile.activemodel-4.0
|
11
|
+
- gemfiles/Gemfile.activemodel-3.2.x
|
12
12
|
|
13
13
|
matrix:
|
14
14
|
exclude:
|
15
15
|
- rvm: 1.8.7
|
16
|
-
gemfile: gemfiles/activemodel-4.0
|
16
|
+
gemfile: gemfiles/Gemfile.activemodel-4.0
|
17
17
|
- rvm: 1.9.2
|
18
|
-
gemfile: gemfiles/activemodel-4.0
|
18
|
+
gemfile: gemfiles/Gemfile.activemodel-4.0
|
19
19
|
|
20
20
|
script: "echo 'COME ON!' && bundle exec rake spec"
|
data/README.md
CHANGED
@@ -534,6 +534,25 @@ article.title # => "Hello world."
|
|
534
534
|
|
535
535
|
Of course, you can use both `include_root_in_json` and `parse_root_in_json` at the same time.
|
536
536
|
|
537
|
+
#### ActiveModel::Serializers support
|
538
|
+
|
539
|
+
If the API returns data in the default format used by the
|
540
|
+
[ActiveModel::Serializers](https://github.com/rails-api/active_model_serializers)
|
541
|
+
project you need to configure Her as follows:
|
542
|
+
|
543
|
+
```ruby
|
544
|
+
class User
|
545
|
+
include Her::Model
|
546
|
+
parse_root_in_json true, format: :active_model_serializers
|
547
|
+
end
|
548
|
+
|
549
|
+
user = Users.find(1)
|
550
|
+
# GET "/users/1", response is { "user": { "id": 1, "fullname": "Lindsay Fünke"} }
|
551
|
+
|
552
|
+
users = Users.all
|
553
|
+
# GET "/users", response is { "users": [{ "id": 1, "fullname": "Lindsay Fünke"}] }
|
554
|
+
```
|
555
|
+
|
537
556
|
### Custom requests
|
538
557
|
|
539
558
|
You can easily define custom requests for your models using `custom_get`, `custom_post`, etc.
|
@@ -906,6 +925,7 @@ These [fine folks](https://github.com/remiprev/her/contributors) helped with Her
|
|
906
925
|
* [@jonkarna](https://github.com/jonkarna)
|
907
926
|
* [@aclevy](https://github.com/aclevy)
|
908
927
|
* [@stevschmid](https://github.com/stevschmid)
|
928
|
+
* [@prognostikos](https://github.com/prognostikos)
|
909
929
|
|
910
930
|
## License
|
911
931
|
|
@@ -70,6 +70,22 @@ module Her
|
|
70
70
|
end
|
71
71
|
alias all where
|
72
72
|
|
73
|
+
# Fetches the data specified by id
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
# class User
|
77
|
+
# include Her::Model
|
78
|
+
# has_many :comments
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# user = User.find(1)
|
82
|
+
# user.comments.find(3) # Fetched via GET "/users/1/comments/3
|
83
|
+
def find(id)
|
84
|
+
return nil if id.blank?
|
85
|
+
path = build_association_path lambda { "#{@parent.request_path(@params)}#{@opts[:path]}/#{id}" }
|
86
|
+
@klass.get(path, @params)
|
87
|
+
end
|
88
|
+
|
73
89
|
# @private
|
74
90
|
def nil?
|
75
91
|
fetch.nil?
|
data/lib/her/model/attributes.rb
CHANGED
@@ -32,7 +32,7 @@ module Her
|
|
32
32
|
#
|
33
33
|
# @private
|
34
34
|
def self.initialize_collection(klass, parsed_data={})
|
35
|
-
collection_data = parsed_data
|
35
|
+
collection_data = klass.extract_array(parsed_data).map do |item_data|
|
36
36
|
resource = klass.new(klass.parse(item_data))
|
37
37
|
resource.run_callbacks :find
|
38
38
|
resource
|
data/lib/her/model/http.rb
CHANGED
@@ -64,7 +64,7 @@ module Her
|
|
64
64
|
path = build_request_path_from_string_or_symbol(path, params)
|
65
65
|
params = to_params(params) unless #{method.to_sym.inspect} == :get
|
66
66
|
send(:'#{method}_raw', path, params) do |parsed_data, response|
|
67
|
-
if parsed_data[:data].is_a?(Array)
|
67
|
+
if parsed_data[:data].is_a?(Array) || active_model_serializers_format?
|
68
68
|
new_collection(parsed_data)
|
69
69
|
else
|
70
70
|
new(parse(parsed_data[:data]).merge :_metadata => parsed_data[:metadata], :_errors => parsed_data[:errors])
|
data/lib/her/model/orm.rb
CHANGED
@@ -115,7 +115,7 @@ module Her
|
|
115
115
|
# User.all # Called via GET "/users?admin=1"
|
116
116
|
# User.new.admin # => 1
|
117
117
|
def default_scope(block=nil)
|
118
|
-
@_her_default_scope ||= superclass.respond_to?(:default_scope) ? superclass.default_scope : scoped
|
118
|
+
@_her_default_scope ||= (!respond_to?(:default_scope) && superclass.respond_to?(:default_scope)) ? superclass.default_scope : scoped
|
119
119
|
@_her_default_scope = @_her_default_scope.instance_exec(&block) unless block.nil?
|
120
120
|
@_her_default_scope
|
121
121
|
end
|
data/lib/her/model/parse.rb
CHANGED
@@ -19,7 +19,7 @@ module Her
|
|
19
19
|
# @param [Hash] data
|
20
20
|
# @private
|
21
21
|
def parse(data)
|
22
|
-
parse_root_in_json? ? data
|
22
|
+
parse_root_in_json? ? data.fetch(parsed_root_element) { data } : data
|
23
23
|
end
|
24
24
|
|
25
25
|
# @private
|
@@ -51,13 +51,14 @@ module Her
|
|
51
51
|
# include Her::Model
|
52
52
|
# parse_root_in_json true
|
53
53
|
# end
|
54
|
-
def parse_root_in_json(value = nil)
|
54
|
+
def parse_root_in_json(value = nil, options = {})
|
55
55
|
@_her_parse_root_in_json ||= begin
|
56
56
|
superclass.parse_root_in_json if superclass.respond_to?(:parse_root_in_json)
|
57
57
|
end
|
58
58
|
|
59
59
|
return @_her_parse_root_in_json unless value
|
60
60
|
@_her_parse_root_in_json = value
|
61
|
+
@_her_parse_root_in_json_format = options[:format]
|
61
62
|
end
|
62
63
|
alias parse_root_in_json? parse_root_in_json
|
63
64
|
|
@@ -97,6 +98,38 @@ module Her
|
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
101
|
+
# Extract an array from the request data
|
102
|
+
#
|
103
|
+
# @example
|
104
|
+
# # with parse_root_in_json true, :format => :active_model_serializers
|
105
|
+
# class User
|
106
|
+
# include Her::Model
|
107
|
+
# parse_root_in_json true, :format => :active_model_serializers
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
# users = User.all # { :users => [ { :id => 1, :name => "Tobias" } ] }
|
111
|
+
# users.first.name # => "Tobias"
|
112
|
+
#
|
113
|
+
# # without parse_root_in_json
|
114
|
+
# class User
|
115
|
+
# include Her::Model
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# users = User.all # [ { :id => 1, :name => "Tobias" } ]
|
119
|
+
# users.first.name # => "Tobias"
|
120
|
+
def extract_array(request_data)
|
121
|
+
if active_model_serializers_format?
|
122
|
+
request_data[:data][pluralized_parsed_root_element]
|
123
|
+
else
|
124
|
+
request_data[:data]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# @private
|
129
|
+
def pluralized_parsed_root_element
|
130
|
+
parsed_root_element.to_s.pluralize.to_sym
|
131
|
+
end
|
132
|
+
|
100
133
|
# @private
|
101
134
|
def included_root_element
|
102
135
|
include_root_in_json == true ? root_element : include_root_in_json
|
@@ -106,6 +139,11 @@ module Her
|
|
106
139
|
def parsed_root_element
|
107
140
|
parse_root_in_json == true ? root_element : parse_root_in_json
|
108
141
|
end
|
142
|
+
|
143
|
+
# @private
|
144
|
+
def active_model_serializers_format?
|
145
|
+
@_her_parse_root_in_json_format == :active_model_serializers
|
146
|
+
end
|
109
147
|
end
|
110
148
|
end
|
111
149
|
end
|
data/lib/her/version.rb
CHANGED
@@ -91,6 +91,7 @@ describe Her::Model::Associations do
|
|
91
91
|
stub.get("/users/2") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :organization_id => 2 }.to_json] }
|
92
92
|
stub.get("/users/1/comments") { |env| [200, {}, [{ :comment => { :id => 4, :body => "They're having a FIRESALE?" } }].to_json] }
|
93
93
|
stub.get("/users/2/comments") { |env| [200, {}, [{ :comment => { :id => 4, :body => "They're having a FIRESALE?" } }, { :comment => { :id => 5, :body => "Is this the tiny town from Footloose?" } }].to_json] }
|
94
|
+
stub.get("/users/2/comments/5") { |env| [200, {}, { :comment => { :id => 5, :body => "Is this the tiny town from Footloose?" } }.to_json] }
|
94
95
|
stub.get("/users/2/role") { |env| [200, {}, { :id => 2, :body => "User" }.to_json] }
|
95
96
|
stub.get("/users/1/role") { |env| [200, {}, { :id => 3, :body => "User" }.to_json] }
|
96
97
|
stub.get("/users/1/posts") { |env| [200, {}, [{:id => 1, :body => 'blogging stuff', :admin_id => 1 }].to_json] }
|
@@ -211,6 +212,11 @@ describe Her::Model::Associations do
|
|
211
212
|
@user_without_included_data.organization.name.should == "Bluth Company"
|
212
213
|
end
|
213
214
|
|
215
|
+
it "fetches data with the specified id when calling find" do
|
216
|
+
comment = @user_without_included_data.comments.find(5)
|
217
|
+
comment.id.should eq(5)
|
218
|
+
end
|
219
|
+
|
214
220
|
[:create, :save_existing, :destroy].each do |type|
|
215
221
|
context "after #{type}" do
|
216
222
|
let(:subject) { self.send("user_with_included_data_after_#{type}")}
|
data/spec/model/parse_spec.rb
CHANGED
@@ -150,6 +150,50 @@ describe Her::Model::Parse do
|
|
150
150
|
@new_user.fullname.should == "Lindsay Fünke"
|
151
151
|
end
|
152
152
|
end
|
153
|
+
|
154
|
+
context "to true with :format => :active_model_serializers" do
|
155
|
+
before do
|
156
|
+
Her::API.default_api.connection.adapter :test do |stub|
|
157
|
+
stub.post("/users") { |env| [200, {}, { :user => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
158
|
+
stub.get("/users") { |env| [200, {}, { :users => [ { :id => 1, :fullname => "Lindsay Fünke" } ] }.to_json] }
|
159
|
+
stub.get("/users/admins") { |env| [200, {}, { :users => [ { :id => 1, :fullname => "Lindsay Fünke" } ] }.to_json] }
|
160
|
+
stub.get("/users/1") { |env| [200, {}, { :user => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json] }
|
161
|
+
stub.put("/users/1") { |env| [200, {}, { :user => { :id => 1, :fullname => "Tobias Fünke Jr." } }.to_json] }
|
162
|
+
end
|
163
|
+
|
164
|
+
spawn_model("Foo::User") do
|
165
|
+
parse_root_in_json true, :format => :active_model_serializers
|
166
|
+
custom_get :admins
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
it "parse the data from the JSON root element after .create" do
|
171
|
+
@new_user = Foo::User.create(:fullname => "Lindsay Fünke")
|
172
|
+
@new_user.fullname.should == "Lindsay Fünke"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "parse the data from the JSON root element after an arbitrary HTTP request" do
|
176
|
+
@users = Foo::User.admins
|
177
|
+
@users.first.fullname.should == "Lindsay Fünke"
|
178
|
+
end
|
179
|
+
|
180
|
+
it "parse the data from the JSON root element after .all" do
|
181
|
+
@users = Foo::User.all
|
182
|
+
@users.first.fullname.should == "Lindsay Fünke"
|
183
|
+
end
|
184
|
+
|
185
|
+
it "parse the data from the JSON root element after .find" do
|
186
|
+
@user = Foo::User.find(1)
|
187
|
+
@user.fullname.should == "Lindsay Fünke"
|
188
|
+
end
|
189
|
+
|
190
|
+
it "parse the data from the JSON root element after .save" do
|
191
|
+
@user = Foo::User.find(1)
|
192
|
+
@user.fullname = "Tobias Fünke"
|
193
|
+
@user.save
|
194
|
+
@user.fullname.should == "Tobias Fünke Jr."
|
195
|
+
end
|
196
|
+
end
|
153
197
|
end
|
154
198
|
|
155
199
|
context "when to_params is set" do
|
data/spec/model/paths_spec.rb
CHANGED
@@ -125,6 +125,28 @@ describe Her::Model::Paths do
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
+
context "children model" do
|
129
|
+
before do
|
130
|
+
Her::API.setup :url => "https://api.example.com" do |builder|
|
131
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
132
|
+
builder.use Faraday::Request::UrlEncoded
|
133
|
+
builder.adapter :test do |stub|
|
134
|
+
stub.get("/users/foo") { |env| [200, {}, { :id => 'foo' }.to_json] }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
spawn_model("Foo::Model") { include_root_in_json true }
|
139
|
+
|
140
|
+
class User < Foo::Model; end
|
141
|
+
@spawned_models << :User
|
142
|
+
end
|
143
|
+
|
144
|
+
it "builds path using the children model name" do
|
145
|
+
User.find('foo').id.should == 'foo'
|
146
|
+
User.find('foo').id.should == 'foo'
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
128
150
|
context "nested model" do
|
129
151
|
before do
|
130
152
|
spawn_model "Foo::User"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: her
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -156,7 +156,8 @@ files:
|
|
156
156
|
- README.md
|
157
157
|
- Rakefile
|
158
158
|
- UPGRADE.md
|
159
|
-
- gemfiles/activemodel-
|
159
|
+
- gemfiles/Gemfile.activemodel-3.2.x
|
160
|
+
- gemfiles/Gemfile.activemodel-4.0
|
160
161
|
- her.gemspec
|
161
162
|
- lib/her.rb
|
162
163
|
- lib/her/api.rb
|
@@ -223,7 +224,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
223
224
|
version: '0'
|
224
225
|
segments:
|
225
226
|
- 0
|
226
|
-
hash:
|
227
|
+
hash: 2536489429371279776
|
227
228
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
229
|
none: false
|
229
230
|
requirements:
|
@@ -232,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
233
|
version: '0'
|
233
234
|
segments:
|
234
235
|
- 0
|
235
|
-
hash:
|
236
|
+
hash: 2536489429371279776
|
236
237
|
requirements: []
|
237
238
|
rubyforge_project:
|
238
239
|
rubygems_version: 1.8.23
|