her 0.5.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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 Version](https://badge.fury.io/rb/her.png)][gem]
|
4
|
+
[![Build Status](https://secure.travis-ci.org/remiprev/her.png?branch=master)][travis]
|
5
|
+
[![Dependency Status](https://gemnasium.com/remiprev/her.png?travis)][gemnasium]
|
6
|
+
[![Code Climate](https://codeclimate.com/github/remiprev/her.png)][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
|