her 0.5.5 → 0.6
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 +8 -8
- data/.gitignore +1 -1
- data/README.md +78 -63
- data/UPGRADE.md +21 -0
- data/lib/her/model.rb +2 -1
- data/lib/her/model/associations.rb +17 -54
- data/lib/her/model/associations/association.rb +46 -0
- data/lib/her/model/associations/belongs_to_association.rb +34 -0
- data/lib/her/model/associations/has_many_association.rb +43 -0
- data/lib/her/model/associations/has_one_association.rb +33 -0
- data/lib/her/model/attributes.rb +19 -19
- data/lib/her/model/base.rb +5 -0
- data/lib/her/model/http.rb +17 -21
- data/lib/her/model/orm.rb +11 -35
- data/lib/her/model/parse.rb +4 -12
- data/lib/her/model/paths.rb +3 -2
- data/lib/her/model/relation.rb +113 -0
- data/lib/her/version.rb +1 -1
- data/spec/model/associations_spec.rb +48 -4
- data/spec/model/introspection_spec.rb +1 -1
- data/spec/model/orm_spec.rb +21 -102
- data/spec/model/parse_spec.rb +36 -7
- data/spec/model/paths_spec.rb +3 -3
- data/spec/model/relation_spec.rb +89 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/macros/her_macros.rb +17 -0
- data/spec/support/macros/request_macros.rb +19 -0
- metadata +13 -37
- data/examples/grape-and-her/.env.default +0 -3
- data/examples/grape-and-her/Procfile +0 -2
- data/examples/grape-and-her/README.md +0 -27
- data/examples/grape-and-her/api/Gemfile +0 -11
- data/examples/grape-and-her/api/Rakefile +0 -14
- data/examples/grape-and-her/api/app/api.rb +0 -49
- data/examples/grape-and-her/api/app/models/organization.rb +0 -7
- data/examples/grape-and-her/api/app/models/user.rb +0 -9
- data/examples/grape-and-her/api/app/views/organizations/_base.rabl +0 -2
- data/examples/grape-and-her/api/app/views/organizations/index.rabl +0 -3
- data/examples/grape-and-her/api/app/views/organizations/show.rabl +0 -3
- data/examples/grape-and-her/api/app/views/users/_base.rabl +0 -8
- data/examples/grape-and-her/api/app/views/users/index.rabl +0 -3
- data/examples/grape-and-her/api/app/views/users/show.rabl +0 -3
- data/examples/grape-and-her/api/config.ru +0 -5
- data/examples/grape-and-her/api/config/boot.rb +0 -17
- data/examples/grape-and-her/api/config/unicorn.rb +0 -7
- data/examples/grape-and-her/api/db/migrations/001_create_users.rb +0 -11
- data/examples/grape-and-her/api/db/migrations/002_create_organizations.rb +0 -8
- data/examples/grape-and-her/consumer/Gemfile +0 -23
- data/examples/grape-and-her/consumer/app/assets/stylesheets/application.scss +0 -190
- data/examples/grape-and-her/consumer/app/assets/stylesheets/reset.scss +0 -53
- data/examples/grape-and-her/consumer/app/consumer.rb +0 -74
- data/examples/grape-and-her/consumer/app/models/organization.rb +0 -13
- data/examples/grape-and-her/consumer/app/models/user.rb +0 -13
- data/examples/grape-and-her/consumer/app/views/index.haml +0 -9
- data/examples/grape-and-her/consumer/app/views/layout.haml +0 -20
- data/examples/grape-and-her/consumer/app/views/organizations/index.haml +0 -25
- data/examples/grape-and-her/consumer/app/views/organizations/show.haml +0 -11
- data/examples/grape-and-her/consumer/app/views/users/index.haml +0 -33
- data/examples/grape-and-her/consumer/app/views/users/show.haml +0 -9
- data/examples/grape-and-her/consumer/config.ru +0 -20
- data/examples/grape-and-her/consumer/config/boot.rb +0 -30
- data/examples/grape-and-her/consumer/config/unicorn.rb +0 -7
- data/examples/grape-and-her/consumer/lib/response_logger.rb +0 -18
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NWYxMjI2MTQ0YjdhOTYyNDA1YTkwZjU4MTNhMDFjZDQ1OTM0OTczMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDk0YzAxYjUzYTlmMGU4Y2FkMGQ0NGQ2MDM0YjM2MjBlZmRmMGVhZg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDE1MWExN2JkZDY5OGYwNWFkMGZhYTVhZDE1MzEzYjMxYjc3YTU3NDc0MDQ4
|
10
|
+
OWMyOTEwMzY3ZTE4OGIxMTNiODlhZDExZGNjMzVlMjYzMWY1ZWNmZGVlM2Qz
|
11
|
+
Yjk2ZWRkZDkxMGU0MmJlMmU2ZjU0ZGI3ODA3ZWU2NDUzNTcxZWQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OTcxYzViZjM1MDVkMDJjODhlZTlkN2M3MTliYzRmZDE1NzQ4NDMzMDgzYzhk
|
14
|
+
NjNhMGIwMjUxNzFiMzA4Mjg2NmE3OTQzNWRhNWNiMDIyM2Q4MzVlMDk3OWM3
|
15
|
+
OTAwNTBlNWYxMmY1MWUwMTlkOWFlYTZkY2E1NDA3NGFkNDdjZjk=
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
# Her
|
1
|
+
# Her
|
2
|
+
|
3
|
+
[][gem]
|
4
|
+
[][travis]
|
5
|
+
[][gemnasium]
|
6
|
+
[][codeclimate]
|
7
|
+
|
8
|
+
[gem]: https://rubygems.org/gems/her
|
9
|
+
[travis]: http://travis-ci.org/remiprev/her
|
10
|
+
[gemnasium]: https://gemnasium.com/remiprev/her
|
11
|
+
[codeclimate]: https://codeclimate.com/github/remiprev/her
|
2
12
|
|
3
13
|
Her is an ORM (Object Relational Mapper) that maps REST resources to Ruby objects. It is designed to build applications that are powered by a RESTful API instead of a database.
|
4
14
|
|
@@ -18,7 +28,7 @@ First, you have to define which API your models will be bound to. For example, w
|
|
18
28
|
|
19
29
|
```ruby
|
20
30
|
# config/initializers/her.rb
|
21
|
-
Her::API.setup :
|
31
|
+
Her::API.setup url: "https://api.example.com" do |connection|
|
22
32
|
connection.use Faraday::Request::UrlEncoded
|
23
33
|
connection.use Her::Middleware::DefaultParseJSON
|
24
34
|
connection.use Faraday::Adapter::NetHttp
|
@@ -42,10 +52,10 @@ User.all
|
|
42
52
|
User.find(1)
|
43
53
|
# GET https://api.example.com/users/1 and return a User object
|
44
54
|
|
45
|
-
@user = User.create(:
|
55
|
+
@user = User.create(fullname: "Tobias Fünke")
|
46
56
|
# POST "https://api.example.com/users" with the data and return a User object
|
47
57
|
|
48
|
-
@user = User.new(:
|
58
|
+
@user = User.new(fullname: "Tobias Fünke")
|
49
59
|
@user.occupation = "actor"
|
50
60
|
@user.save
|
51
61
|
# POST https://api.example.com/users with the data and return a User object
|
@@ -68,11 +78,11 @@ end
|
|
68
78
|
# Update a fetched resource
|
69
79
|
user = User.find(1)
|
70
80
|
user.fullname = "Lindsay Fünke"
|
71
|
-
# OR user.assign_attributes
|
81
|
+
# OR user.assign_attributes(fullname: "Lindsay Fünke")
|
72
82
|
user.save
|
73
83
|
|
74
84
|
# Update a resource without fetching it
|
75
|
-
User.save_existing(1, :
|
85
|
+
User.save_existing(1, fullname: "Lindsay Fünke")
|
76
86
|
|
77
87
|
# Destroy a fetched resource
|
78
88
|
user = User.find(1)
|
@@ -83,20 +93,21 @@ User.destroy_existing(1)
|
|
83
93
|
|
84
94
|
# Fetching a collection of resources
|
85
95
|
User.all
|
96
|
+
User.where(moderator: 1).all
|
86
97
|
|
87
98
|
# Create a new resource
|
88
|
-
User.create(:
|
99
|
+
User.create(fullname: "Maeby Fünke")
|
89
100
|
|
90
101
|
# Save a new resource
|
91
|
-
user = User.new(:
|
102
|
+
user = User.new(fullname: "Maeby Fünke")
|
92
103
|
user.save
|
93
104
|
```
|
94
105
|
|
95
|
-
You can look into the `
|
106
|
+
You can look into the [`her-example`](https://github.com/remiprev/her-example) repository for a sample application using Her. For a complete reference of all the methods you can use, check out [the documentation](http://rdoc.info/github/remiprev/her).
|
96
107
|
|
97
108
|
## Middleware
|
98
109
|
|
99
|
-
Since Her relies on [Faraday](https://github.com/
|
110
|
+
Since Her relies on [Faraday](https://github.com/lostisland/faraday) to send HTTP requests, you can choose the middleware used to handle requests and responses. Using the block in the `setup` call, you have access to Faraday’s `connection` object and are able to customize the middleware stack used on each request and response.
|
100
111
|
|
101
112
|
### Authentication
|
102
113
|
|
@@ -126,7 +137,7 @@ end
|
|
126
137
|
# config/initializers/her.rb
|
127
138
|
require "lib/my_token_authentication"
|
128
139
|
|
129
|
-
Her::API.setup :
|
140
|
+
Her::API.setup url: "https://api.example.com" do |connection|
|
130
141
|
connection.use MyTokenAuthentication
|
131
142
|
connection.use Faraday::Request::UrlEncoded
|
132
143
|
connection.use Her::Middleware::DefaultParseJSON
|
@@ -153,13 +164,13 @@ In your Ruby code:
|
|
153
164
|
```ruby
|
154
165
|
# Create an application on `https://dev.twitter.com/apps` to set these values
|
155
166
|
TWITTER_CREDENTIALS = {
|
156
|
-
:
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
167
|
+
consumer_key: "",
|
168
|
+
consumer_secret: "",
|
169
|
+
token: "",
|
170
|
+
token_secret: ""
|
160
171
|
}
|
161
172
|
|
162
|
-
Her::API.setup :
|
173
|
+
Her::API.setup url: "https://api.twitter.com/1/" do |connection|
|
163
174
|
connection.use FaradayMiddleware::OAuth, TWITTER_CREDENTIALS
|
164
175
|
connection.use Her::Middleware::DefaultParseJSON
|
165
176
|
connection.use Faraday::Adapter::NetHttp
|
@@ -188,7 +199,7 @@ By default, Her handles JSON data. It expects the resource/collection data to be
|
|
188
199
|
|
189
200
|
However, if you want Her to be able to parse the data from a single root element (usually based on the model name), you’ll have to use the `parse_root_in_json` method (See the **JSON attributes-wrapping** section).
|
190
201
|
|
191
|
-
Also, you can define your own parsing method using a response middleware. The middleware should set `env[:body]` to a hash with three keys:
|
202
|
+
Also, you can define your own parsing method using a response middleware. The middleware should set `env[:body]` to a hash with three symbol keys: `:data`, `:errors` and `:metadata`. The following code uses a custom middleware to parse the JSON data:
|
192
203
|
|
193
204
|
```ruby
|
194
205
|
# Expects responses like:
|
@@ -198,21 +209,21 @@ Also, you can define your own parsing method using a response middleware. The mi
|
|
198
209
|
# "id": 1,
|
199
210
|
# "name": "Tobias Fünke"
|
200
211
|
# },
|
201
|
-
# "errors"
|
212
|
+
# "errors": []
|
202
213
|
# }
|
203
214
|
#
|
204
215
|
class MyCustomParser < Faraday::Response::Middleware
|
205
216
|
def on_complete(env)
|
206
|
-
json = MultiJson.load(env[:body], :
|
217
|
+
json = MultiJson.load(env[:body], symbolize_keys: true)
|
207
218
|
env[:body] = {
|
208
|
-
:
|
209
|
-
:
|
210
|
-
:
|
219
|
+
data: json[:result],
|
220
|
+
errors: json[:errors],
|
221
|
+
metadata: json[:metadata]
|
211
222
|
}
|
212
223
|
end
|
213
224
|
end
|
214
225
|
|
215
|
-
Her::API.setup :
|
226
|
+
Her::API.setup url: "https://api.example.com" do |connection|
|
216
227
|
connection.use MyCustomParser
|
217
228
|
connection.use Faraday::Adapter::NetHttp
|
218
229
|
end
|
@@ -233,7 +244,7 @@ gem "memcached"
|
|
233
244
|
In your Ruby code:
|
234
245
|
|
235
246
|
```ruby
|
236
|
-
Her::API.setup :
|
247
|
+
Her::API.setup url: "https://api.example.com" do |connection|
|
237
248
|
connection.use FaradayMiddleware::Caching, Memcached::Rails.new('127.0.0.1:11211')
|
238
249
|
connection.use Her::Middleware::DefaultParseJSON
|
239
250
|
connection.use Faraday::Adapter::NetHttp
|
@@ -289,14 +300,14 @@ If there’s association data in the resource, no extra HTTP request is made whe
|
|
289
300
|
```ruby
|
290
301
|
@user = User.find(1)
|
291
302
|
# {
|
292
|
-
# :
|
293
|
-
# :
|
294
|
-
# :
|
295
|
-
# { :
|
296
|
-
# { :
|
303
|
+
# "id": 1,
|
304
|
+
# "name": "George Michael Bluth",
|
305
|
+
# "comments": [
|
306
|
+
# { "id": 1, "text": "Foo" },
|
307
|
+
# { "id": 2, "text": "Bar" }
|
297
308
|
# ],
|
298
|
-
# :
|
299
|
-
# :
|
309
|
+
# "role": { "id": 1, "name": "Admin" },
|
310
|
+
# "organization": { "id": 2, "name": "Bluth Company" }
|
300
311
|
# }
|
301
312
|
@user.comments
|
302
313
|
# [#<Comment id=1 text="Foo">, #<Comment id=2 text="Bar">]
|
@@ -310,13 +321,17 @@ If there’s no association data in the resource, Her makes a HTTP request to re
|
|
310
321
|
|
311
322
|
```ruby
|
312
323
|
@user = User.find(1)
|
313
|
-
# { :
|
324
|
+
# { "id": 1, "name": "George Michael Bluth", "organization_id": 2 }
|
314
325
|
|
315
326
|
# has_many association:
|
316
327
|
@user.comments
|
317
328
|
# GET /users/1/comments
|
318
329
|
# [#<Comment id=1>, #<Comment id=2>]
|
319
330
|
|
331
|
+
@user.comments.where(approved: 1)
|
332
|
+
# GET /users/1/comments?approved=1
|
333
|
+
# [#<Comment id=1>]
|
334
|
+
|
320
335
|
# has_one association:
|
321
336
|
@user.role
|
322
337
|
# GET /users/1/role
|
@@ -364,11 +379,11 @@ class User
|
|
364
379
|
include Her::Model
|
365
380
|
|
366
381
|
attributes :fullname, :email
|
367
|
-
validates :fullname, :
|
368
|
-
validates :email, :
|
382
|
+
validates :fullname, presence: true
|
383
|
+
validates :email, presence: true
|
369
384
|
end
|
370
385
|
|
371
|
-
@user = User.new(:
|
386
|
+
@user = User.new(fullname: "Tobias Fünke")
|
372
387
|
@user.valid? # => false
|
373
388
|
|
374
389
|
@user.save
|
@@ -386,7 +401,7 @@ class User
|
|
386
401
|
attributes :fullname, :email
|
387
402
|
end
|
388
403
|
|
389
|
-
@user = User.new(:
|
404
|
+
@user = User.new(fullname: "Tobias Fünke")
|
390
405
|
@user.fullname_changed? # => true
|
391
406
|
@user.changes # => { :fullname => [nil, "Tobias Fünke"] }
|
392
407
|
|
@@ -412,7 +427,7 @@ class User
|
|
412
427
|
end
|
413
428
|
end
|
414
429
|
|
415
|
-
@user = User.create(:
|
430
|
+
@user = User.create(fullname: "Tobias Funke")
|
416
431
|
# POST /users&fullname=Tobias+Fünke&internal_id=42
|
417
432
|
|
418
433
|
@user = User.find(1)
|
@@ -450,10 +465,10 @@ class Article
|
|
450
465
|
include_root_in_json :post
|
451
466
|
end
|
452
467
|
|
453
|
-
User.create(:
|
468
|
+
User.create(fullname: "Tobias Fünke")
|
454
469
|
# POST { "user": { "fullname": "Tobias Fünke" } } to /users
|
455
470
|
|
456
|
-
Article.create(:
|
471
|
+
Article.create(title: "Hello world.")
|
457
472
|
# POST { "post": { "title": "Hello world." } } to /articles
|
458
473
|
```
|
459
474
|
|
@@ -473,11 +488,11 @@ class Article
|
|
473
488
|
end
|
474
489
|
|
475
490
|
# POST /users returns { "user": { "fullname": "Tobias Fünke" } }
|
476
|
-
user = User.create(:
|
491
|
+
user = User.create(fullname: "Tobias Fünke")
|
477
492
|
user.fullname # => "Tobias Fünke"
|
478
493
|
|
479
494
|
# POST /articles returns { "post": { "title": "Hello world." } }
|
480
|
-
article = Article.create(:
|
495
|
+
article = Article.create(title: "Hello world.")
|
481
496
|
article.title # => "Hello world."
|
482
497
|
```
|
483
498
|
|
@@ -502,7 +517,7 @@ User.unpopular
|
|
502
517
|
# GET /users/unpopular
|
503
518
|
# [#<User id=3>, #<User id=4>]
|
504
519
|
|
505
|
-
User.from_default(:
|
520
|
+
User.from_default(name: "Maeby Fünke")
|
506
521
|
# POST /users/from_default?name=Maeby+Fünke
|
507
522
|
# #<User id=5 name="Maeby Fünke">
|
508
523
|
```
|
@@ -582,13 +597,13 @@ class User
|
|
582
597
|
collection_path "/organizations/:organization_id/users"
|
583
598
|
end
|
584
599
|
|
585
|
-
@user = User.find(1, :
|
600
|
+
@user = User.find(1, _organization_id: 2)
|
586
601
|
# GET /organizations/2/users/1
|
587
602
|
|
588
|
-
@user = User.all(:
|
603
|
+
@user = User.all(_organization_id: 2)
|
589
604
|
# GET /organizations/2/users
|
590
605
|
|
591
|
-
@user = User.new(:
|
606
|
+
@user = User.new(fullname: "Tobias Fünke", organization_id: 2)
|
592
607
|
@user.save
|
593
608
|
# POST /organizations/2/users
|
594
609
|
```
|
@@ -603,8 +618,8 @@ class User
|
|
603
618
|
primary_key :_id
|
604
619
|
end
|
605
620
|
|
606
|
-
user = User.find(
|
607
|
-
user.save # PUT /users/
|
621
|
+
user = User.find("4fd89a42ff204b03a905c535") # GET /users/1 returns { "_id": "4fd89a42ff204b03a905c535", "name": "Tobias" }
|
622
|
+
user.save # PUT /users/4fd89a42ff204b03a905c535
|
608
623
|
```
|
609
624
|
|
610
625
|
### Inheritance
|
@@ -634,14 +649,14 @@ It is possible to use different APIs for different models. Instead of calling `H
|
|
634
649
|
|
635
650
|
```ruby
|
636
651
|
# config/initializers/her.rb
|
637
|
-
|
638
|
-
|
652
|
+
MY_API = Her::API.new
|
653
|
+
MY_API.setup url: "https://my-api.example.com" do |connection|
|
639
654
|
connection.use Her::Middleware::DefaultParseJSON
|
640
655
|
connection.use Faraday::Adapter::NetHttp
|
641
656
|
end
|
642
657
|
|
643
|
-
|
644
|
-
|
658
|
+
OTHER_API = Her::API.new
|
659
|
+
OTHER_API.setup url: "https://other-api.example.com" do |connection|
|
645
660
|
connection.use Her::Middleware::DefaultParseJSON
|
646
661
|
connection.use Faraday::Adapter::NetHttp
|
647
662
|
end
|
@@ -652,28 +667,28 @@ You can then define which API a model will use:
|
|
652
667
|
```ruby
|
653
668
|
class User
|
654
669
|
include Her::Model
|
655
|
-
|
670
|
+
use_api MY_API
|
656
671
|
end
|
657
672
|
|
658
673
|
class Category
|
659
674
|
include Her::Model
|
660
|
-
|
675
|
+
use_api OTHER_API
|
661
676
|
end
|
662
677
|
|
663
678
|
User.all
|
664
|
-
# GET https://
|
679
|
+
# GET https://my-api.example.com/users
|
665
680
|
|
666
681
|
Category.all
|
667
|
-
# GET https://
|
682
|
+
# GET https://other-api.example.com/categories
|
668
683
|
```
|
669
684
|
|
670
685
|
### SSL
|
671
686
|
|
672
|
-
When initializing `Her::API`, you can pass any parameter supported by `Faraday.new`. So [to use HTTPS](https://github.com/
|
687
|
+
When initializing `Her::API`, you can pass any parameter supported by `Faraday.new`. So [to use HTTPS](https://github.com/lostisland/faraday/wiki/Setting-up-SSL-certificates), you can use Faraday’s `:ssl` option.
|
673
688
|
|
674
689
|
```ruby
|
675
|
-
ssl_options = { :
|
676
|
-
Her::API.setup :
|
690
|
+
ssl_options = { ca_path: "/usr/lib/ssl/certs" }
|
691
|
+
Her::API.setup url: "https://api.example.com", ssl: ssl_options do |connection|
|
677
692
|
connection.use Her::Middleware::DefaultParseJSON
|
678
693
|
connection.use Faraday::Adapter::NetHttp
|
679
694
|
end
|
@@ -704,11 +719,11 @@ In order to test them, we’ll have to stub the remote API requests. With [RSpec
|
|
704
719
|
RSpec.configure do |config|
|
705
720
|
config.include(Module.new do
|
706
721
|
def stub_api_for(klass)
|
707
|
-
klass.
|
722
|
+
klass.use_api (api = Her::API.new)
|
708
723
|
|
709
724
|
# Here, you would customize this for your own API (URL, middleware, etc)
|
710
725
|
# like you have done in your application’s initializer
|
711
|
-
api.setup :
|
726
|
+
api.setup url: "http://api.example.com" do |connection|
|
712
727
|
connection.use Her::Middleware::FirstLevelParseJSON
|
713
728
|
connection.adapter(:test) { |s| yield(s) }
|
714
729
|
end
|
@@ -724,7 +739,7 @@ Then, in your tests, we can specify what (fake) HTTP requests will return:
|
|
724
739
|
describe User do
|
725
740
|
before do
|
726
741
|
stub_api_for(User) do |stub|
|
727
|
-
stub.get("/users/popular") { |env| [200, {}, [{ :
|
742
|
+
stub.get("/users/popular") { |env| [200, {}, [{ id: 1, name: "Tobias Fünke" }, { id: 2, name: "Lindsay Fünke" }].to_json] }
|
728
743
|
end
|
729
744
|
end
|
730
745
|
|
@@ -744,7 +759,7 @@ describe Post do
|
|
744
759
|
describe :recent do
|
745
760
|
before do
|
746
761
|
stub_api_for(Post) do |stub|
|
747
|
-
stub.get("/posts/recent") { |env| [200, {}, [{ :
|
762
|
+
stub.get("/posts/recent") { |env| [200, {}, [{ id: 1 }, { id: 2 }].to_json] }
|
748
763
|
end
|
749
764
|
end
|
750
765
|
|
@@ -756,7 +771,7 @@ describe Post do
|
|
756
771
|
describe :archived do
|
757
772
|
before do
|
758
773
|
stub_api_for(Post) do |stub|
|
759
|
-
stub.get("/posts/archived") { |env| [200, {}, [{ :
|
774
|
+
stub.get("/posts/archived") { |env| [200, {}, [{ id: 1 }, { id: 2 }].to_json] }
|
760
775
|
end
|
761
776
|
end
|
762
777
|
|
data/UPGRADE.md
CHANGED
@@ -2,6 +2,27 @@
|
|
2
2
|
|
3
3
|
Here is a list of backward-incompatible changes that were introduced while Her is pre-1.0. After reaching 1.0, it will follow the [Semantic Versioning](http://semver.org/) system.
|
4
4
|
|
5
|
+
## 0.6
|
6
|
+
|
7
|
+
* Associations have been refactored so that calling the association name method doesn’t immediately load or fetch the data.
|
8
|
+
|
9
|
+
class User
|
10
|
+
include Her::Model
|
11
|
+
has_many :comments
|
12
|
+
end
|
13
|
+
|
14
|
+
# This doesn’t fetch the data yet
|
15
|
+
comments = User.find(1).comments
|
16
|
+
|
17
|
+
# This actually fetches the data
|
18
|
+
puts comments.inspect
|
19
|
+
|
20
|
+
# This is no longer possible
|
21
|
+
comments = User.find(1).comments(:approved => 1)
|
22
|
+
|
23
|
+
# To pass additional parameters to the HTTP request, we now have to do this
|
24
|
+
comments = User.find(1).comments.where(:approved => 1)
|
25
|
+
|
5
26
|
## 0.5.4
|
6
27
|
|
7
28
|
* Her does not support Ruby 1.8.7 anymore. You should upgrade to 1.9.2, 1.9.3 or 2.0.0.
|
data/lib/her/model.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "her/model/base"
|
2
2
|
require "her/model/http"
|
3
3
|
require "her/model/attributes"
|
4
|
+
require "her/model/relation"
|
4
5
|
require "her/model/orm"
|
5
6
|
require "her/model/parse"
|
6
7
|
require "her/model/associations"
|
@@ -44,7 +45,7 @@ module Her
|
|
44
45
|
# Class methods
|
45
46
|
included do
|
46
47
|
# Assign the default API
|
47
|
-
|
48
|
+
use_api Her::API.default_api
|
48
49
|
|
49
50
|
# Define the default primary key
|
50
51
|
primary_key :id
|