her 0.1.1 → 0.1.5
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/LICENSE +3 -0
- data/README.md +156 -10
- data/lib/her/model.rb +1 -0
- data/lib/her/model/http.rb +12 -0
- data/lib/her/model/orm.rb +7 -10
- data/lib/her/model/relationships.rb +37 -9
- data/lib/her/version.rb +1 -1
- data/spec/model_spec.rb +41 -4
- metadata +5 -4
data/LICENSE
ADDED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](http://travis-ci.org/remiprev/her)
|
4
4
|
|
5
|
-
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.
|
5
|
+
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 and no database.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -19,6 +19,7 @@ That’s it!
|
|
19
19
|
First, you have to define which API your models will be bound to. For example, with Rails, you would create a new `config/initializers/her.rb` file with this line:
|
20
20
|
|
21
21
|
```ruby
|
22
|
+
# config/initializers/her.rb
|
22
23
|
Her::API.setup :base_uri => "https://api.example.com"
|
23
24
|
```
|
24
25
|
|
@@ -33,15 +34,82 @@ end
|
|
33
34
|
After that, using Her is very similar to many ActiveModel-like ORMs:
|
34
35
|
|
35
36
|
```ruby
|
36
|
-
User.all
|
37
|
-
|
37
|
+
User.all
|
38
|
+
# GET https://api.example.com/users and return an array of User objects
|
39
|
+
|
40
|
+
User.find(1)
|
41
|
+
# GET https://api.example.com/users/1 and return a User object
|
42
|
+
|
43
|
+
@user = User.create(:fullname => "Tobias Fünke")
|
44
|
+
# POST "https://api.example.com/users" with the data and return a User object
|
45
|
+
|
46
|
+
@user = User.new(:fullname => "Tobias Fünke")
|
47
|
+
@user.occupation = "actor"
|
48
|
+
@user.save
|
49
|
+
# POST https://api.example.com/users with the data and return a User object
|
50
|
+
|
51
|
+
@user = User.find(1)
|
52
|
+
@user.fullname = "Lindsay Fünke"
|
53
|
+
@user.save
|
54
|
+
# PUT https://api.example.com/users/1 with the data and return+update the User object
|
55
|
+
```
|
56
|
+
|
57
|
+
## Parsing data
|
58
|
+
|
59
|
+
By default, Her handles JSON data. It expects the data to be formatted in a certain structure. The default is this:
|
60
|
+
|
61
|
+
```javascript
|
62
|
+
// The response of GET /users/1
|
63
|
+
{
|
64
|
+
"data" : {
|
65
|
+
"id" : 1,
|
66
|
+
"name" : "Tobias Fünke"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
// The response of GET /users
|
71
|
+
{
|
72
|
+
"data" : [
|
73
|
+
{
|
74
|
+
"id" : 1,
|
75
|
+
"name" : "Tobias Fünke"
|
76
|
+
},
|
77
|
+
{
|
78
|
+
"id" : 2,
|
79
|
+
"name" : "Lindsay Fünke"
|
80
|
+
}
|
81
|
+
],
|
82
|
+
"metadata" : {
|
83
|
+
"page" : 1,
|
84
|
+
"per_page" : 10
|
85
|
+
}
|
86
|
+
}
|
87
|
+
```
|
88
|
+
|
89
|
+
However, you can define your own parsing method, with `Her::API.parse_with`. The `parse_with` method takes a block which will be executed each time data from an HTTP response needs to be parsed. The block is expected to return a hash with three keys: `data`, `errors` and `metadata`. The following code enables parsing JSON data and treating this data as first-level properties:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
Her::API.setup :base_uri => "https://api.example.com"
|
93
|
+
Her::API.parse_with |response|
|
94
|
+
json = JSON.parse(response.body, :symbolize_names => true)
|
95
|
+
errors = json.delete(:errors)
|
96
|
+
{
|
97
|
+
:data => json,
|
98
|
+
:errors => errors || [],
|
99
|
+
:metadata => {}
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
# User.find(1) will now expect "https://api.example.com/users/1" to return something like '{ "id": 1, "name": "Tobias Fünke" }'
|
38
104
|
```
|
39
105
|
|
106
|
+
This feature is not stable and might change in the future, probably by using a middleware through [Faraday](https://github.com/technoweenie/faraday).
|
107
|
+
|
40
108
|
## Relationships
|
41
109
|
|
42
|
-
You can define `has_many` relationships in your models. The relationship data is handled in two different ways. When parsing a resource from JSON data, if there’s a relationship data included, it will be used to create new Ruby objects.
|
110
|
+
You can define `has_many`, `has_one` and `belongs_to` relationships in your models. The relationship data is handled in two different ways. When parsing a resource from JSON data, if there’s a relationship data included, it will be used to create new Ruby objects.
|
43
111
|
|
44
|
-
If no relationship data was included when parsing a resource, calling a method with the same name as the relationship will fetch the data (providing there’s an HTTP request available for it).
|
112
|
+
If no relationship data was included when parsing a resource, calling a method with the same name as the relationship will fetch the data (providing there’s an HTTP request available for it in the API).
|
45
113
|
|
46
114
|
For example, with this setup:
|
47
115
|
|
@@ -49,32 +117,58 @@ For example, with this setup:
|
|
49
117
|
class User
|
50
118
|
include Her::Model
|
51
119
|
has_many :comments
|
120
|
+
has_one :role
|
121
|
+
belongs_to :organization
|
52
122
|
end
|
53
123
|
|
54
124
|
class Comment
|
55
125
|
include Her::Model
|
56
126
|
end
|
127
|
+
|
128
|
+
class Role
|
129
|
+
include Her::Model
|
130
|
+
end
|
131
|
+
|
132
|
+
class Organization
|
133
|
+
include Her::Model
|
134
|
+
end
|
57
135
|
```
|
58
136
|
|
59
|
-
|
137
|
+
If there’s relationship data in the resource, no extra HTTP request is made when calling the `#comments` method and an array of resources are returned:
|
60
138
|
|
61
139
|
```ruby
|
62
|
-
@user = User.find(1) # { :data => { :id => 1, :name => "
|
140
|
+
@user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth", :comments => [{ :id => 1, :text => "Foo" }, { :id => 2, :text => "Bar" }], :role => { :id => 1, :name => "Admin" }, :organization => { :id => 2, :name => "Bluth Company" } }}
|
63
141
|
@user.comments # => [#<Comment id=1>, #<Comment id=2>] fetched directly from @user
|
142
|
+
@user.role # => #<Role id=1> fetched directly from @user
|
143
|
+
@user.organization # => #<Organization id=2> fetched directly from @user
|
64
144
|
```
|
65
145
|
|
66
146
|
If there’s no relationship data in the resource, an extra HTTP request (to `GET /users/1/comments`) is made when calling the `#comments` method:
|
67
147
|
|
68
148
|
```ruby
|
69
|
-
@user = User.find(1) # { :data => { :id => 1, :name => "
|
149
|
+
@user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth" }}
|
70
150
|
@user.comments # => [#<Comment id=1>, #<Comment id=2>] fetched from /users/1/comments
|
71
151
|
```
|
72
152
|
|
73
|
-
|
153
|
+
For `has_one` relationship, an extra HTTP request (to `GET /users/1/role`) is made when calling the `#role` method:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
@user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth" }}
|
157
|
+
@user.role # => #<Role id=1> fetched from /users/1/role
|
158
|
+
```
|
159
|
+
|
160
|
+
For `belongs_to` relationship, an extra HTTP request (to `GET /organizations/2`) is made when calling the `#organization` method:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
@user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth", :organization_id => 2 }}
|
164
|
+
@user.organization # => #<Organization id=2> fetched from /organizations/2
|
165
|
+
```
|
166
|
+
|
167
|
+
However, subsequent calls to `#comments` or `#role` will not trigger the extra HTTP request.
|
74
168
|
|
75
169
|
## Custom requests
|
76
170
|
|
77
|
-
You can easily add custom methods for your models. You can either use `get_collection` (which maps the returned data to a collection of resources), `get_resource` (which maps the returned data to a single resource) or `get_raw` (which yields the parsed data return from the HTTP request).
|
171
|
+
You can easily add custom methods for your models. You can either use `get_collection` (which maps the returned data to a collection of resources), `get_resource` (which maps the returned data to a single resource) or `get_raw` (which yields the parsed data return from the HTTP request). Other HTTP methods are supported (`post_raw`, `put_resource`, etc.)
|
78
172
|
|
79
173
|
```ruby
|
80
174
|
class User
|
@@ -94,3 +188,55 @@ end
|
|
94
188
|
User.popular # => [#<User id=1>, #<User id=2>]
|
95
189
|
User.total # => 42
|
96
190
|
```
|
191
|
+
|
192
|
+
## Multiple APIs
|
193
|
+
|
194
|
+
It is possible to use different APIs for different models. Instead of calling `Her::API.setup`, you can create instances of `Her::API`:
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
# config/initializers/her.rb
|
198
|
+
$my_api = Her::API.new
|
199
|
+
$my_api.setup :base_uri => "https://my_api.example.com"
|
200
|
+
|
201
|
+
$other_api = Her::API.new
|
202
|
+
$other_api.setup :base_uri => "https://other_api.example.com"
|
203
|
+
```
|
204
|
+
|
205
|
+
You can then define which API a model will use:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
class User
|
209
|
+
include Her::Model
|
210
|
+
uses_api $my_api
|
211
|
+
end
|
212
|
+
|
213
|
+
class Category
|
214
|
+
include Her::Model
|
215
|
+
uses_api $other_api
|
216
|
+
end
|
217
|
+
|
218
|
+
User.all
|
219
|
+
# GET https://my_api.example.com/users
|
220
|
+
|
221
|
+
Category.all
|
222
|
+
# GET https://other_api.example.com/categories
|
223
|
+
```
|
224
|
+
|
225
|
+
## Things to be done
|
226
|
+
|
227
|
+
* Deleting resources
|
228
|
+
* Support for Faraday middleware to handle caching, alternative formats, etc.
|
229
|
+
* Hooks before save, update, create, destroy, etc.
|
230
|
+
* Better error handling
|
231
|
+
* Better introspection for debug
|
232
|
+
* Better documentation
|
233
|
+
|
234
|
+
## Contributors
|
235
|
+
|
236
|
+
Feel free to contribute and submit issues/pull requests [on GitHub](https://github.com/remiprev/her/issues).
|
237
|
+
|
238
|
+
Take a look at the `spec` folder before you do, and make sure `bundle exec rake spec` passes after your modifications :)
|
239
|
+
|
240
|
+
## License
|
241
|
+
|
242
|
+
Her is © 2012 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [LITL license](https://github.com/remiprev/her/blob/master/LICENSE). See the `LICENSE` file.
|
data/lib/her/model.rb
CHANGED
data/lib/her/model/http.rb
CHANGED
@@ -19,6 +19,18 @@ module Her
|
|
19
19
|
@her_collection_path = path
|
20
20
|
end # }}}
|
21
21
|
|
22
|
+
# Defines a custom item path for the resource
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# class User
|
26
|
+
# include Her::Model
|
27
|
+
# item_path "user"
|
28
|
+
# end
|
29
|
+
def item_path(path=nil) # {{{
|
30
|
+
return @her_item_path unless path
|
31
|
+
@her_item_path = path
|
32
|
+
end # }}}
|
33
|
+
|
22
34
|
# Main request wrapper around Her::API. Used to make custom request to the API.
|
23
35
|
# @private
|
24
36
|
def request(attrs={}, &block) # {{{
|
data/lib/her/model/orm.rb
CHANGED
@@ -9,15 +9,6 @@ module Her
|
|
9
9
|
@data = self.class.parse_relationships(@data)
|
10
10
|
end # }}}
|
11
11
|
|
12
|
-
# Initialize a collection of resources with raw data from an HTTP request
|
13
|
-
#
|
14
|
-
# @example
|
15
|
-
# User.get("/users/popular") { |data| User.new_collection(data) }
|
16
|
-
def new_collection(parsed_data) # {{{
|
17
|
-
collection_data = parsed_data[:data]
|
18
|
-
Her::Model::ORM.initialize_collection(self.to_s.downcase.to_sym, collection_data)
|
19
|
-
end # }}}
|
20
|
-
|
21
12
|
# Initialize a collection of resources
|
22
13
|
# @private
|
23
14
|
def self.initialize_collection(name, collection_data) # {{{
|
@@ -40,6 +31,12 @@ module Her
|
|
40
31
|
end
|
41
32
|
end # }}}
|
42
33
|
|
34
|
+
# Initialize a collection of resources with raw data from an HTTP request
|
35
|
+
def new_collection(parsed_data) # {{{
|
36
|
+
collection_data = parsed_data[:data]
|
37
|
+
Her::Model::ORM.initialize_collection(self.to_s.downcase.to_sym, collection_data)
|
38
|
+
end # }}}
|
39
|
+
|
43
40
|
# Fetch a specific resource based on an ID
|
44
41
|
def find(id, params={}) # {{{
|
45
42
|
request(params.merge(:_method => :get, :_path => "#{@her_collection_path}/#{id}")) do |parsed_data|
|
@@ -50,7 +47,7 @@ module Her
|
|
50
47
|
# Fetch a collection of resources
|
51
48
|
def all(params={}) # {{{
|
52
49
|
request(params.merge(:_method => :get, :_path => "#{@her_collection_path}")) do |parsed_data|
|
53
|
-
|
50
|
+
new_collection(parsed_data)
|
54
51
|
end
|
55
52
|
end # }}}
|
56
53
|
|
@@ -14,7 +14,15 @@ module Her
|
|
14
14
|
@her_relationships ||= {}
|
15
15
|
@her_relationships.each_pair do |type, relationships|
|
16
16
|
relationships.each do |relationship|
|
17
|
-
|
17
|
+
if data.include?(relationship[:name])
|
18
|
+
if type == :has_many
|
19
|
+
data[relationship[:name]] = Her::Model::ORM.initialize_collection(relationship[:name], data[relationship[:name]])
|
20
|
+
elsif type == :has_one
|
21
|
+
data[relationship[:name]] = Object.const_get(relationship[:name].to_s.classify).new(data[relationship[:name]])
|
22
|
+
elsif type == :belongs_to
|
23
|
+
data[relationship[:name]] = Object.const_get(relationship[:name].to_s.classify).new(data[relationship[:name]])
|
24
|
+
end
|
25
|
+
end
|
18
26
|
end
|
19
27
|
end
|
20
28
|
data
|
@@ -24,9 +32,9 @@ module Her
|
|
24
32
|
#
|
25
33
|
# * `User.has_many :comments` is used to check if the "user" JSON
|
26
34
|
# resource we receive has a `comments` key and map it to an array
|
27
|
-
# of Comment
|
35
|
+
# of Comment objects
|
28
36
|
# * `User.has_many :comments` creates a User.comments method to would
|
29
|
-
# make an extra HTTP request if there was no "comments" key
|
37
|
+
# make an extra HTTP request (to `/users/:id/comments`) if there was no "comments" key
|
30
38
|
def has_many(name, attrs={}) # {{{
|
31
39
|
@her_relationships ||= {}
|
32
40
|
(@her_relationships[:has_many] ||= []) << attrs.merge(:name => name)
|
@@ -38,18 +46,38 @@ module Her
|
|
38
46
|
end
|
39
47
|
end # }}}
|
40
48
|
|
41
|
-
# Define
|
49
|
+
# Define an *has_one* relationship for the resource
|
42
50
|
#
|
43
|
-
# * `User.
|
44
|
-
# resource we receive has
|
45
|
-
#
|
51
|
+
# * `User.has_one :category` is used to check if the "category" JSON
|
52
|
+
# resource we receive has a `category` key and map it to a Category object
|
53
|
+
# * `User.has_one :category` creates a User.category method to would
|
54
|
+
# make an extra HTTP request (to `/users/category`) if there was no "category" key
|
55
|
+
def has_one(name, attrs={}) # {{{
|
56
|
+
@her_relationships ||= {}
|
57
|
+
(@her_relationships[:has_one] ||= []) << attrs.merge(:name => name)
|
58
|
+
collection_path = @her_collection_path
|
59
|
+
|
60
|
+
define_method(name) do
|
61
|
+
return @data[name] if @data.include?(name) # Do not fetch from API again if we have it in @data
|
62
|
+
self.class.get_resource("#{collection_path}/#{id}/#{Object.const_get(name.to_s.classify).item_path}")
|
63
|
+
end
|
64
|
+
end # }}}
|
65
|
+
|
66
|
+
# Define a *belongs_to* relationship for the resource
|
46
67
|
#
|
47
|
-
# * `User.belongs_to :
|
68
|
+
# * `User.belongs_to :organization` is used to check if the "organization" JSON
|
69
|
+
# resource we receive has a `organization` key and map it to an Organization object
|
70
|
+
# * `User.belongs_to :organization` creates a User.organization method to would
|
71
|
+
# make an extra HTTP request (to `/organizations/:organization_id`) if there was no "organization" key
|
48
72
|
def belongs_to(name, attrs={}) # {{{
|
49
73
|
@her_relationships ||= {}
|
50
74
|
(@her_relationships[:belongs_to] ||= []) << attrs.merge(:name => name)
|
75
|
+
collection_path = @her_collection_path
|
51
76
|
|
52
|
-
|
77
|
+
define_method(name) do
|
78
|
+
return @data[name] if @data.include?(name) # Do not fetch from API again if we have it in @data
|
79
|
+
self.class.get_resource("#{Object.const_get(name.to_s.classify).collection_path}/#{@data["#{name}_id".to_sym]}")
|
80
|
+
end
|
53
81
|
end # }}}
|
54
82
|
end
|
55
83
|
end
|
data/lib/her/version.rb
CHANGED
data/spec/model_spec.rb
CHANGED
@@ -214,12 +214,12 @@ describe Her::Model do
|
|
214
214
|
end
|
215
215
|
end # }}}
|
216
216
|
|
217
|
-
it "handle resource data update without saving it" do
|
217
|
+
it "handle resource data update without saving it" do # {{{
|
218
218
|
@user = User.find(1)
|
219
219
|
@user.fullname.should == "Tobias Fünke"
|
220
220
|
@user.fullname = "Kittie Sanchez"
|
221
221
|
@user.fullname.should == "Kittie Sanchez"
|
222
|
-
end
|
222
|
+
end # }}}
|
223
223
|
|
224
224
|
it "handle resource update through #save on an existing resource" do # {{{
|
225
225
|
@user = User.find(1)
|
@@ -250,6 +250,17 @@ describe Her::Model do
|
|
250
250
|
User.relationships[:has_many].should == [{ :name => :comments }, { :name => :posts }]
|
251
251
|
end # }}}
|
252
252
|
|
253
|
+
it "handles a single 'has_one' relationship" do # {{{
|
254
|
+
User.has_one :category
|
255
|
+
User.relationships[:has_one].should == [{ :name => :category }]
|
256
|
+
end # }}}
|
257
|
+
|
258
|
+
it "handles multiples 'has_one' relationship" do # {{{
|
259
|
+
User.has_one :category
|
260
|
+
User.has_one :role
|
261
|
+
User.relationships[:has_one].should == [{ :name => :category }, { :name => :role }]
|
262
|
+
end # }}}
|
263
|
+
|
253
264
|
it "handles a single belongs_to relationship" do # {{{
|
254
265
|
User.belongs_to :organization
|
255
266
|
User.relationships[:belongs_to].should == [{ :name => :organization }]
|
@@ -265,20 +276,34 @@ describe Her::Model do
|
|
265
276
|
context "handling relationships" do
|
266
277
|
before do # {{{
|
267
278
|
Her::API.setup :base_uri => "https://api.example.com"
|
268
|
-
FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke", :comments => [{ :id => 2, :body => "Tobias, you blow hard!" }, { :id => 3, :body => "I wouldn't mind kissing that man between the cheeks, so to speak" }] } }.to_json)
|
269
|
-
FakeWeb.register_uri(:get, "https://api.example.com/users/2", :body => { :data => { :id => 2, :name => "Lindsay Fünke" } }.to_json)
|
279
|
+
FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke", :comments => [{ :id => 2, :body => "Tobias, you blow hard!" }, { :id => 3, :body => "I wouldn't mind kissing that man between the cheeks, so to speak" }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 1, :name => "Bluth Company" }, :organization_id => 1 } }.to_json)
|
280
|
+
FakeWeb.register_uri(:get, "https://api.example.com/users/2", :body => { :data => { :id => 2, :name => "Lindsay Fünke", :organization_id => 1 } }.to_json)
|
270
281
|
FakeWeb.register_uri(:get, "https://api.example.com/users/2/comments", :body => { :data => [{ :id => 4, :body => "They're having a FIRESALE?" }, { :id => 5, :body => "Is this the tiny town from Footloose?" }] }.to_json)
|
282
|
+
FakeWeb.register_uri(:get, "https://api.example.com/users/2/role", :body => { :data => { :id => 2, :body => "User" } }.to_json)
|
283
|
+
FakeWeb.register_uri(:get, "https://api.example.com/organizations/1", :body => { :data => { :id => 1, :name => "Bluth Company" } }.to_json)
|
271
284
|
|
272
285
|
Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
|
273
286
|
class User
|
274
287
|
include Her::Model
|
275
288
|
has_many :comments
|
289
|
+
has_one :role
|
290
|
+
belongs_to :organization
|
291
|
+
end
|
292
|
+
|
293
|
+
Object.instance_eval { remove_const :Organization } if Object.const_defined?(:Organization)
|
294
|
+
class Organization
|
295
|
+
include Her::Model
|
276
296
|
end
|
277
297
|
|
278
298
|
Object.instance_eval { remove_const :Comment } if Object.const_defined?(:Comment)
|
279
299
|
class Comment
|
280
300
|
include Her::Model
|
281
301
|
end
|
302
|
+
|
303
|
+
Object.instance_eval { remove_const :Role } if Object.const_defined?(:Role)
|
304
|
+
class Role
|
305
|
+
include Her::Model
|
306
|
+
end
|
282
307
|
end # }}}
|
283
308
|
|
284
309
|
it "maps an array of included data" do # {{{
|
@@ -286,6 +311,12 @@ describe Her::Model do
|
|
286
311
|
@user.comments.length.should == 2
|
287
312
|
@user.comments.first.id.should == 2
|
288
313
|
@user.comments.first.body.should == "Tobias, you blow hard!"
|
314
|
+
|
315
|
+
@user.role.id.should == 1
|
316
|
+
@user.role.body.should == "Admin"
|
317
|
+
|
318
|
+
@user.organization.id.should == 1
|
319
|
+
@user.organization.name.should == "Bluth Company"
|
289
320
|
end # }}}
|
290
321
|
|
291
322
|
it "fetches data that was not included" do # {{{
|
@@ -293,6 +324,12 @@ describe Her::Model do
|
|
293
324
|
@user.comments.length.should == 2
|
294
325
|
@user.comments.first.id.should == 4
|
295
326
|
@user.comments.first.body.should == "They're having a FIRESALE?"
|
327
|
+
|
328
|
+
@user.role.id.should == 2
|
329
|
+
@user.role.body.should == "User"
|
330
|
+
|
331
|
+
@user.organization.id.should == 1
|
332
|
+
@user.organization.name.should == "Bluth Company"
|
296
333
|
end # }}}
|
297
334
|
end
|
298
335
|
end
|
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.1.
|
4
|
+
version: 0.1.5
|
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: 2012-04-
|
12
|
+
date: 2012-04-11 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -165,6 +165,7 @@ files:
|
|
165
165
|
- .gitignore
|
166
166
|
- .travis.yml
|
167
167
|
- Gemfile
|
168
|
+
- LICENSE
|
168
169
|
- README.md
|
169
170
|
- Rakefile
|
170
171
|
- her.gemspec
|
@@ -193,7 +194,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
193
194
|
version: '0'
|
194
195
|
segments:
|
195
196
|
- 0
|
196
|
-
hash: -
|
197
|
+
hash: -4167601811325738400
|
197
198
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
199
|
none: false
|
199
200
|
requirements:
|
@@ -202,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
203
|
version: '0'
|
203
204
|
segments:
|
204
205
|
- 0
|
205
|
-
hash: -
|
206
|
+
hash: -4167601811325738400
|
206
207
|
requirements: []
|
207
208
|
rubyforge_project:
|
208
209
|
rubygems_version: 1.8.18
|