her 0.6.7 → 0.6.8
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.
- 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
|