her 0.2.6 → 0.3

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/.gitignore CHANGED
@@ -4,3 +4,4 @@ Gemfile.lock
4
4
  pkg/*
5
5
  .yardoc
6
6
  doc
7
+ rake
data/README.md CHANGED
@@ -64,14 +64,16 @@ You can look into the `examples` directory for sample applications using Her.
64
64
 
65
65
  ## Middleware
66
66
 
67
- Since Her relies on [Faraday](https://github.com/technoweenie/faraday) to send HTTP requests, you can add additional middleware 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.
67
+ Since Her relies on [Faraday](https://github.com/technoweenie/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.
68
68
 
69
69
  ### Authentication
70
70
 
71
- Her doesn’t support any kind of authentication. However, it’s very easy to implement one with a request middleware. Using the connection block, we add it to the default list of middleware.
71
+ Her doesn’t support authentication by default. However, it’s easy to implement one with request middleware. Using the `connection` block, we can add it to the middleware stack.
72
+
73
+ For example, to add a API token header to your requests, you would do something like this:
72
74
 
73
75
  ```ruby
74
- class MyAuthentication < Faraday::Middleware
76
+ class TokenAuthentication < Faraday::Middleware
75
77
  def initialize(app, options={})
76
78
  @options = options
77
79
  end
@@ -84,7 +86,7 @@ end
84
86
 
85
87
  Her::API.setup :url => "https://api.example.com" do |connection|
86
88
  # This token could be stored in the client session
87
- connection.use MyAuthentication, :token => "bb2b2dd75413d32c1ac421d39e95b978d1819ff611f68fc2fdd5c8b9c7331192"
89
+ connection.use TokenAuthentication, :token => "bb2b2dd75413d32c1ac421d39e95b978d1819ff611f68fc2fdd5c8b9c7331192"
88
90
 
89
91
  connection.use Faraday::Request::UrlEncoded
90
92
  connection.use Her::Middleware::DefaultParseJSON
@@ -106,9 +108,19 @@ By default, Her handles JSON data. It expects the resource/collection data to be
106
108
  [{ "id" : 1, "name" : "Tobias Fünke" }]
107
109
  ```
108
110
 
109
- However, you can define your own parsing method, using a response middleware. The middleware is expected to set `env[:body]` to a hash with three keys: `data`, `errors` and `metadata`. The following code enables parsing JSON data and treating the result as first-level properties. Using the connection block, we then replace the default parser with our custom parser.
111
+ However, you can define your own parsing method using a response middleware. The middleware should set `env[:body]` to a hash with three keys: `data`, `errors` and `metadata`. The following code uses a custom middleware to parse the JSON data:
110
112
 
111
113
  ```ruby
114
+ # Expects responses like:
115
+ #
116
+ # {
117
+ # "result": {
118
+ # "id": 1,
119
+ # "name": "Tobias Fünke"
120
+ # },
121
+ # "errors" => []
122
+ # }
123
+ #
112
124
  class MyCustomParser < Faraday::Response::Middleware
113
125
  def on_complete(env)
114
126
  json = MultiJson.load(env[:body], :symbolize_keys => true)
@@ -125,7 +137,6 @@ Her::API.setup :url => "https://api.example.com" do |connection|
125
137
  connection.use MyCustomParser
126
138
  connection.use Faraday::Adapter::NetHttp
127
139
  end
128
- # User.find(1) will now expect "https://api.example.com/users/1" to return something like '{ "result" => { "id": 1, "name": "Tobias Fünke" }, "errors" => [] }'
129
140
  ```
130
141
 
131
142
  ### OAuth
@@ -219,11 +230,12 @@ end
219
230
 
220
231
  ## Relationships
221
232
 
222
- You can define `has_many`, `has_one` and `belongs_to` relationships in your models. The relationship data is handled in two different ways. If there’s relationship data when parsing a resource, it will be used to create new Ruby objects.
233
+ You can define `has_many`, `has_one` and `belongs_to` relationships in your models. The relationship data is handled in two different ways.
223
234
 
224
- 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).
235
+ 1. If Her finds relationship data when parsing a resource, that data will be used to create the associated model objects on the resource.
236
+ 2. 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).
225
237
 
226
- For example, with this setup:
238
+ For example:
227
239
 
228
240
  ```ruby
229
241
  class User
@@ -249,34 +261,51 @@ end
249
261
  If there’s relationship data in the resource, no extra HTTP request is made when calling the `#comments` method and an array of resources is returned:
250
262
 
251
263
  ```ruby
252
- @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" } }}
253
- @user.comments # => [#<Comment id=1>, #<Comment id=2>] fetched directly from @user
254
- @user.role # => #<Role id=1> fetched directly from @user
255
- @user.organization # => #<Organization id=2> fetched directly from @user
256
- ```
257
-
258
- 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:
259
-
260
- ```ruby
261
- @user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth" }}
262
- @user.comments # => [#<Comment id=1>, #<Comment id=2>] fetched from /users/1/comments
264
+ @user = User.find(1)
265
+ # {
266
+ # :data => {
267
+ # :id => 1,
268
+ # :name => "George Michael Bluth",
269
+ # :comments => [
270
+ # { :id => 1, :text => "Foo" },
271
+ # { :id => 2, :text => "Bar" }
272
+ # ],
273
+ # :role => { :id => 1, :name => "Admin" },
274
+ # :organization => { :id => 2, :name => "Bluth Company" }
275
+ # }
276
+ # }
277
+ @user.comments
278
+ # [#<Comment id=1 text="Foo">, #<Comment id=2 text="Bar">]
279
+ @user.role
280
+ # #<Role id=1 name="Admin">
281
+ @user.organization
282
+ # #<Organization id=2 name="Bluth Company">
263
283
  ```
264
284
 
265
- For `has_one` relationships, an extra HTTP request (to `GET /users/1/role`) is made when calling the `#role` method:
285
+ If there’s no relationship data in the resource, Her makes a HTTP request to retrieve the data.
266
286
 
267
287
  ```ruby
268
- @user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth" }}
269
- @user.role # => #<Role id=1> fetched from /users/1/role
270
- ```
271
-
272
- For `belongs_to` relationships, an extra HTTP request (to `GET /organizations/2`) is made when calling the `#organization` method:
273
-
274
- ```ruby
275
- @user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth", :organization_id => 2 }}
276
- @user.organization # => #<Organization id=2> fetched from /organizations/2
288
+ @user = User.find(1)
289
+ # { :data => { :id => 1, :name => "George Michael Bluth", :organization_id => 2 }}
290
+
291
+ # has_many relationship:
292
+ @user.comments
293
+ # GET /users/1/comments
294
+ # [#<Comment id=1>, #<Comment id=2>]
295
+
296
+ # has_one relationship:
297
+ @user.role
298
+ # GET /users/1/role
299
+ # #<Role id=1>
300
+
301
+ # belongs_to relationship:
302
+ @user.organization
303
+ # (the organization id comes from :organization_id, by default)
304
+ # GET /organizations/2
305
+ # #<Organization id=2>
277
306
  ```
278
307
 
279
- However, subsequent calls to `#comments`, `#role` and `#organization` will not trigger extra HTTP requests as the data has already been fetched.
308
+ Subsequent calls to `#comments`, `#role` and `#organization` will not trigger extra HTTP requests and will return the cached objects.
280
309
 
281
310
  ## Hooks
282
311
 
@@ -307,14 +336,17 @@ class User
307
336
  custom_post :from_default
308
337
  end
309
338
 
310
- User.popular # => [#<User id=1>, #<User id=2>]
339
+ User.popular
311
340
  # GET /users/popular
341
+ # [#<User id=1>, #<User id=2>]
312
342
 
313
- User.unpopular # => [#<User id=3>, #<User id=4>]
343
+ User.unpopular
314
344
  # GET /users/unpopular
345
+ # [#<User id=3>, #<User id=4>]
315
346
 
316
- User.from_default(:name => "Maeby Fünke") # => #<User id=5>
347
+ User.from_default(:name => "Maeby Fünke")
317
348
  # POST /users/from_default?name=Maeby+Fünke
349
+ # #<User id=5 name="Maeby Fünke">
318
350
  ```
319
351
 
320
352
  You can also use `get`, `post`, `put` or `delete` (which maps the returned data to either a collection or a resource).
@@ -324,11 +356,13 @@ class User
324
356
  include Her::Model
325
357
  end
326
358
 
327
- User.get(:popular) # => [#<User id=1>, #<User id=2>]
359
+ User.get(:popular)
328
360
  # GET /users/popular
361
+ # [#<User id=1>, #<User id=2>]
329
362
 
330
- User.get(:single_best) # => #<User id=1>
363
+ User.get(:single_best)
331
364
  # GET /users/single_best
365
+ # #<User id=1>
332
366
  ```
333
367
 
334
368
  Also, `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) can also be used. Other HTTP methods are supported (`post_raw`, `put_resource`, etc.).
@@ -348,8 +382,12 @@ class User
348
382
  end
349
383
  end
350
384
 
351
- User.popular # => [#<User id=1>, #<User id=2>]
352
- User.total # => 42
385
+ User.popular
386
+ # GET /users/popular
387
+ # [#<User id=1>, #<User id=2>]
388
+ User.total
389
+ # GET /users/stats
390
+ # => 42
353
391
  ```
354
392
 
355
393
  You can also use full request paths (with strings instead of symbols).
@@ -359,8 +397,9 @@ class User
359
397
  include Her::Model
360
398
  end
361
399
 
362
- User.get("/users/popular") # => [#<User id=1>, #<User id=2>]
400
+ User.get("/users/popular")
363
401
  # GET /users/popular
402
+ # [#<User id=1>, #<User id=2>]
364
403
  ```
365
404
 
366
405
  ## Custom paths
@@ -1,6 +1,33 @@
1
1
  module Her
2
2
  module Model
3
3
  module Introspection
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ # Finds a class at the same level as this one or at the global level.
8
+ def nearby_class(name)
9
+ sibling_class(name) || name.constantize rescue nil
10
+ end
11
+
12
+ protected
13
+ # Looks for a class at the same level as this one with the given name.
14
+ # @private
15
+ def sibling_class(name)
16
+ if mod = self.containing_module
17
+ "#{mod.name}::#{name}".constantize rescue nil
18
+ else
19
+ name.constantize rescue nil
20
+ end
21
+ end
22
+
23
+ # If available, returns the containing Module for this class.
24
+ # @private
25
+ def containing_module # {{{
26
+ return unless self.name =~ /::/
27
+ self.name.split("::")[0..-2].join("::").constantize
28
+ end # }}}
29
+ end
30
+
4
31
  # Inspect an element, returns it for introspection.
5
32
  #
6
33
  # @example
@@ -20,10 +20,8 @@ module Her
20
20
 
21
21
  # Initialize a collection of resources
22
22
  # @private
23
- def self.initialize_collection(name, parsed_data={}) # {{{
24
- collection_data = parsed_data[:data].map do |item_data|
25
- Object.const_get(name.to_s.classify).new(item_data)
26
- end
23
+ def self.initialize_collection(klass, parsed_data={}) # {{{
24
+ collection_data = parsed_data[:data].map { |item_data| klass.new(item_data) }
27
25
  Her::Collection.new(collection_data, parsed_data[:metadata], parsed_data[:errors])
28
26
  end # }}}
29
27
 
@@ -54,7 +52,7 @@ module Her
54
52
  #
55
53
  # @param [Array] parsed_data
56
54
  def new_collection(parsed_data) # {{{
57
- Her::Model::ORM.initialize_collection(self.to_s.underscore, parsed_data)
55
+ Her::Model::ORM.initialize_collection(self, parsed_data)
58
56
  end # }}}
59
57
 
60
58
  # Return `true` if a resource was not saved yet
@@ -35,8 +35,12 @@ module Her
35
35
  # end
36
36
  #
37
37
  # User.all # Fetched via GET /utilisateurs
38
- def build_request_path(parameters={}) # {{{
39
- (path = parameters.include?(:id) ? @her_resource_path : @her_collection_path).gsub(/:([\w_]+)/) do
38
+ def build_request_path(path=nil, parameters={}) # {{{
39
+ unless path.is_a?(String)
40
+ parameters = path || {}
41
+ path = parameters.include?(:id) ? @her_resource_path : @her_collection_path
42
+ end
43
+ path.gsub(/:([\w_]+)/) do
40
44
  # Look for :key or :_key, otherwise raise an exception
41
45
  parameters[$1.to_sym] || parameters["_#{$1}".to_sym] || raise(Her::Errors::PathError.new("Missing :_#{$1} parameter to build the request path (#{path})."))
42
46
  end
@@ -15,13 +15,13 @@ module Her
15
15
  @her_relationships.each_pair do |type, relationships|
16
16
  relationships.each do |relationship|
17
17
  name = relationship[:name]
18
- class_name = relationship[:class_name]
18
+ klass = self.nearby_class(relationship[:class_name])
19
19
  next if !data.include?(name) or data[name].nil?
20
20
  data[name] = case type
21
21
  when :has_many
22
- Her::Model::ORM.initialize_collection(class_name, :data => data[name])
22
+ Her::Model::ORM.initialize_collection(klass, :data => data[name])
23
23
  when :has_one, :belongs_to
24
- Object.const_get(class_name).new(data[name])
24
+ klass.new(data[name])
25
25
  else
26
26
  nil
27
27
  end
@@ -49,8 +49,18 @@ module Her
49
49
  # @user.articles # => [#<Article(articles/2) id=2 title="Hello world.">]
50
50
  # # Fetched via GET "/users/1/articles"
51
51
  def has_many(name, attrs={}) # {{{
52
- attrs = { :class_name => name.to_s.classify, :name => name }.merge(attrs)
53
- define_relationship(:has_many, attrs)
52
+ @her_relationships ||= {}
53
+ attrs = {
54
+ :class_name => name.to_s.classify,
55
+ :name => name,
56
+ :path => "/#{name}"
57
+ }.merge(attrs)
58
+ (@her_relationships[:has_many] ||= []) << attrs
59
+
60
+ define_method(name) do
61
+ klass = self.class.nearby_class(attrs[:class_name])
62
+ @data[name] ||= klass.get_collection("#{self.class.build_request_path(:id => id)}#{attrs[:path]}")
63
+ end
54
64
  end # }}}
55
65
 
56
66
  # Define an *has_one* relationship.
@@ -72,8 +82,18 @@ module Her
72
82
  # @user.organization # => #<Organization(organizations/2) id=2 name="Foobar Inc.">
73
83
  # # Fetched via GET "/users/1/organization"
74
84
  def has_one(name, attrs={}) # {{{
75
- attrs = { :class_name => name.to_s.classify, :name => name }.merge(attrs)
76
- define_relationship(:has_one, attrs)
85
+ @her_relationships ||= {}
86
+ attrs = {
87
+ :class_name => name.to_s.classify,
88
+ :name => name,
89
+ :path => "/#{name}"
90
+ }.merge(attrs)
91
+ (@her_relationships[:has_one] ||= []) << attrs
92
+
93
+ define_method(name) do
94
+ klass = self.class.nearby_class(attrs[:class_name])
95
+ @data[name] ||= klass.get_resource("#{self.class.build_request_path(:id => id)}#{attrs[:path]}")
96
+ end
77
97
  end # }}}
78
98
 
79
99
  # Define a *belongs_to* relationship.
@@ -84,10 +104,10 @@ module Her
84
104
  # @example
85
105
  # class User
86
106
  # include Her::API
87
- # belongs_to :team
107
+ # belongs_to :team, :class_name => "Group"
88
108
  # end
89
109
  #
90
- # class Team
110
+ # class Group
91
111
  # include Her::API
92
112
  # end
93
113
  #
@@ -95,36 +115,28 @@ module Her
95
115
  # @user.team # => #<Team(teams/2) id=2 name="Developers">
96
116
  # # Fetched via GET "/teams/2"
97
117
  def belongs_to(name, attrs={}) # {{{
98
- attrs = { :class_name => name.to_s.classify, :name => name, :foreign_key => "#{name}_id" }.merge(attrs)
99
- define_relationship(:belongs_to, attrs)
100
- end # }}}
101
-
102
- private
103
- # @private
104
- def define_relationship(type, attrs) # {{{
105
118
  @her_relationships ||= {}
106
- (@her_relationships[type] ||= []) << attrs
107
- relationship_accessor(type, attrs)
108
- end # }}}
119
+ attrs = {
120
+ :class_name => name.to_s.classify,
121
+ :name => name,
122
+ :foreign_key => "#{name}_id",
123
+ :path => "/#{name.to_s.pluralize}/:id"
124
+ }.merge(attrs)
125
+ (@her_relationships[:belongs_to] ||= []) << attrs
126
+
127
+ define_method(name) do
128
+ klass = self.class.nearby_class(attrs[:class_name])
129
+ @data[name] ||= klass.get_resource("#{klass.build_request_path(:id => @data[attrs[:foreign_key].to_sym])}")
130
+ end
131
+ end
109
132
 
110
133
  # @private
111
134
  def relationship_accessor(type, attrs) # {{{
112
135
  name = attrs[:name]
113
136
  class_name = attrs[:class_name]
114
137
  define_method(name) do
115
- return @data[name] if @data.include?(name)
116
-
117
- klass = Object.const_get(class_name)
118
- path = self.class.build_request_path(:id => id)
119
- @data[name] = case type
120
- when :belongs_to
121
- foreign_key = attrs[:foreign_key].to_sym
122
- klass.get_resource("#{klass.build_request_path(:id => @data[foreign_key])}")
123
- when :has_many
124
- klass.get_collection("#{path}/#{name.to_s.pluralize}")
125
- when :has_one
126
- klass.get_resource("#{path}/#{name.to_s.singularize}")
127
- end
138
+ klass = self.class.nearby_class(attrs[:class_name])
139
+ @data[name] ||= klass.get_resource("#{klass.build_request_path(attrs[:path], :id => @data[attrs[:foreign_key].to_sym])}")
128
140
  end
129
141
  end # }}}
130
142
  end
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3"
3
3
  end
@@ -4,154 +4,154 @@ require File.join(File.dirname(__FILE__), "../spec_helper.rb")
4
4
  describe Her::Model::Hooks do
5
5
  context "adding hooks to a model" do
6
6
  before do # {{{
7
- spawn_model :User
7
+ spawn_model "Foo::User"
8
8
  end # }}}
9
9
 
10
10
  describe "method hooks" do
11
11
  it "handles “before save” method hooks" do # {{{
12
- User.before_save :set_internal_id
13
- User.send(:hooks)[:before_save].length.should == 1
14
- User.send(:hooks)[:before_save].first.class.should == Symbol
12
+ Foo::User.before_save :set_internal_id
13
+ Foo::User.send(:hooks)[:before_save].length.should == 1
14
+ Foo::User.send(:hooks)[:before_save].first.class.should == Symbol
15
15
  end # }}}
16
16
 
17
17
  it "handles “before create” method hooks" do # {{{
18
- User.before_create :set_internal_id
19
- User.send(:hooks)[:before_create].length.should == 1
20
- User.send(:hooks)[:before_create].first.class.should == Symbol
18
+ Foo::User.before_create :set_internal_id
19
+ Foo::User.send(:hooks)[:before_create].length.should == 1
20
+ Foo::User.send(:hooks)[:before_create].first.class.should == Symbol
21
21
  end # }}}
22
22
 
23
23
  it "handles “before update” method hooks" do # {{{
24
- User.before_update :set_internal_id
25
- User.send(:hooks)[:before_update].length.should == 1
26
- User.send(:hooks)[:before_update].first.class.should == Symbol
24
+ Foo::User.before_update :set_internal_id
25
+ Foo::User.send(:hooks)[:before_update].length.should == 1
26
+ Foo::User.send(:hooks)[:before_update].first.class.should == Symbol
27
27
  end # }}}
28
28
 
29
29
  it "handles “before destroy” method hooks" do # {{{
30
- User.before_destroy :set_internal_id
31
- User.send(:hooks)[:before_destroy].length.should == 1
32
- User.send(:hooks)[:before_destroy].first.class.should == Symbol
30
+ Foo::User.before_destroy :set_internal_id
31
+ Foo::User.send(:hooks)[:before_destroy].length.should == 1
32
+ Foo::User.send(:hooks)[:before_destroy].first.class.should == Symbol
33
33
  end # }}}
34
34
 
35
35
  it "handles “after save” method hooks" do # {{{
36
- User.after_save :set_internal_id
37
- User.send(:hooks)[:after_save].length.should == 1
38
- User.send(:hooks)[:after_save].first.class.should == Symbol
36
+ Foo::User.after_save :set_internal_id
37
+ Foo::User.send(:hooks)[:after_save].length.should == 1
38
+ Foo::User.send(:hooks)[:after_save].first.class.should == Symbol
39
39
  end # }}}
40
40
 
41
41
  it "handles “after create” method hooks" do # {{{
42
- User.after_create :set_internal_id
43
- User.send(:hooks)[:after_create].length.should == 1
44
- User.send(:hooks)[:after_create].first.class.should == Symbol
42
+ Foo::User.after_create :set_internal_id
43
+ Foo::User.send(:hooks)[:after_create].length.should == 1
44
+ Foo::User.send(:hooks)[:after_create].first.class.should == Symbol
45
45
  end # }}}
46
46
 
47
47
  it "handles “after update” method hooks" do # {{{
48
- User.after_update :set_internal_id
49
- User.send(:hooks)[:after_update].length.should == 1
50
- User.send(:hooks)[:after_update].first.class.should == Symbol
48
+ Foo::User.after_update :set_internal_id
49
+ Foo::User.send(:hooks)[:after_update].length.should == 1
50
+ Foo::User.send(:hooks)[:after_update].first.class.should == Symbol
51
51
  end # }}}
52
52
 
53
53
  it "handles “after destroy” method hooks" do # {{{
54
- User.after_destroy :set_internal_id
55
- User.send(:hooks)[:after_destroy].length.should == 1
56
- User.send(:hooks)[:after_destroy].first.class.should == Symbol
54
+ Foo::User.after_destroy :set_internal_id
55
+ Foo::User.send(:hooks)[:after_destroy].length.should == 1
56
+ Foo::User.send(:hooks)[:after_destroy].first.class.should == Symbol
57
57
  end # }}}
58
58
  end
59
59
 
60
60
  describe "block hooks" do
61
61
  it "handles “before save” block hooks" do # {{{
62
- User.before_save { |record| record.internal_id = 42 }
63
- User.send(:hooks)[:before_save].length.should == 1
64
- User.send(:hooks)[:before_save].first.class.should == Proc
62
+ Foo::User.before_save { |record| record.internal_id = 42 }
63
+ Foo::User.send(:hooks)[:before_save].length.should == 1
64
+ Foo::User.send(:hooks)[:before_save].first.class.should == Proc
65
65
  end # }}}
66
66
 
67
67
  it "handles “before create” block hooks" do # {{{
68
- User.before_create { |record| record.internal_id = 42 }
69
- User.send(:hooks)[:before_create].length.should == 1
70
- User.send(:hooks)[:before_create].first.class.should == Proc
68
+ Foo::User.before_create { |record| record.internal_id = 42 }
69
+ Foo::User.send(:hooks)[:before_create].length.should == 1
70
+ Foo::User.send(:hooks)[:before_create].first.class.should == Proc
71
71
  end # }}}
72
72
 
73
73
  it "handles “before update” block hooks" do # {{{
74
- User.before_update { |record| record.internal_id = 42 }
75
- User.send(:hooks)[:before_update].length.should == 1
76
- User.send(:hooks)[:before_update].first.class.should == Proc
74
+ Foo::User.before_update { |record| record.internal_id = 42 }
75
+ Foo::User.send(:hooks)[:before_update].length.should == 1
76
+ Foo::User.send(:hooks)[:before_update].first.class.should == Proc
77
77
  end # }}}
78
78
 
79
79
  it "handles “before destroy” block hooks" do # {{{
80
- User.before_destroy { |record| record.internal_id = 42 }
81
- User.send(:hooks)[:before_destroy].length.should == 1
82
- User.send(:hooks)[:before_destroy].first.class.should == Proc
80
+ Foo::User.before_destroy { |record| record.internal_id = 42 }
81
+ Foo::User.send(:hooks)[:before_destroy].length.should == 1
82
+ Foo::User.send(:hooks)[:before_destroy].first.class.should == Proc
83
83
  end # }}}
84
84
 
85
85
  it "handles “after save” block hooks" do # {{{
86
- User.after_save { |record| record.internal_id = 42 }
87
- User.send(:hooks)[:after_save].length.should == 1
88
- User.send(:hooks)[:after_save].first.class.should == Proc
86
+ Foo::User.after_save { |record| record.internal_id = 42 }
87
+ Foo::User.send(:hooks)[:after_save].length.should == 1
88
+ Foo::User.send(:hooks)[:after_save].first.class.should == Proc
89
89
  end # }}}
90
90
 
91
91
  it "handles “after create” block hooks" do # {{{
92
- User.after_create { |record| record.internal_id = 42 }
93
- User.send(:hooks)[:after_create].length.should == 1
94
- User.send(:hooks)[:after_create].first.class.should == Proc
92
+ Foo::User.after_create { |record| record.internal_id = 42 }
93
+ Foo::User.send(:hooks)[:after_create].length.should == 1
94
+ Foo::User.send(:hooks)[:after_create].first.class.should == Proc
95
95
  end # }}}
96
96
 
97
97
  it "handles “after update” block hooks" do # {{{
98
- User.after_update { |record| record.internal_id = 42 }
99
- User.send(:hooks)[:after_update].length.should == 1
100
- User.send(:hooks)[:after_update].first.class.should == Proc
98
+ Foo::User.after_update { |record| record.internal_id = 42 }
99
+ Foo::User.send(:hooks)[:after_update].length.should == 1
100
+ Foo::User.send(:hooks)[:after_update].first.class.should == Proc
101
101
  end # }}}
102
102
 
103
103
  it "handles “after destroy” block hooks" do # {{{
104
- User.after_destroy { |record| record.internal_id = 42 }
105
- User.send(:hooks)[:after_destroy].length.should == 1
106
- User.send(:hooks)[:after_destroy].first.class.should == Proc
104
+ Foo::User.after_destroy { |record| record.internal_id = 42 }
105
+ Foo::User.send(:hooks)[:after_destroy].length.should == 1
106
+ Foo::User.send(:hooks)[:after_destroy].first.class.should == Proc
107
107
  end # }}}
108
108
  end
109
109
  end
110
110
 
111
111
  context "perform hooks on a model" do
112
- before do # {{{
113
- Her::API.setup :url => "https://api.example.com" do |builder|
114
- builder.use Her::Middleware::FirstLevelParseJSON
115
- builder.use Faraday::Request::UrlEncoded
116
- builder.adapter :test do |stub|
117
- stub.post("/users") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
118
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
119
- stub.put("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
120
- stub.delete("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
121
- end
122
- end
123
-
124
- spawn_model :User do
125
- attr_accessor :internal_save_id, :internal_create_id, :internal_update_id, :internal_destroy_id
126
- attr_accessor :internal_after_save_id, :internal_after_create_id, :internal_after_update_id, :internal_after_destroy_id
127
-
128
- def change_internal_save_id; @internal_save_id = 100; end
129
- def change_internal_create_id; @internal_create_id = 101; end
130
- def change_internal_update_id; @internal_update_id = 102; end
131
- def change_internal_destroy_id; @internal_destroy_id = 103; end
132
-
133
- def change_internal_after_save_id; @internal_after_save_id = 100; end
134
- def change_internal_after_create_id; @internal_after_create_id = 101; end
135
- def change_internal_after_update_id; @internal_after_update_id = 102; end
136
- def change_internal_after_destroy_id; @internal_after_destroy_id = 103; end
112
+ before do # {{{
113
+ Her::API.setup :url => "https://api.example.com" do |builder|
114
+ builder.use Her::Middleware::FirstLevelParseJSON
115
+ builder.use Faraday::Request::UrlEncoded
116
+ builder.adapter :test do |stub|
117
+ stub.post("/users") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
118
+ stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
119
+ stub.put("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
120
+ stub.delete("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
137
121
  end
138
- end # }}}
122
+ end
123
+
124
+ spawn_model "Foo::User" do
125
+ attr_accessor :internal_save_id, :internal_create_id, :internal_update_id, :internal_destroy_id
126
+ attr_accessor :internal_after_save_id, :internal_after_create_id, :internal_after_update_id, :internal_after_destroy_id
127
+
128
+ def change_internal_save_id; @internal_save_id = 100; end
129
+ def change_internal_create_id; @internal_create_id = 101; end
130
+ def change_internal_update_id; @internal_update_id = 102; end
131
+ def change_internal_destroy_id; @internal_destroy_id = 103; end
132
+
133
+ def change_internal_after_save_id; @internal_after_save_id = 100; end
134
+ def change_internal_after_create_id; @internal_after_create_id = 101; end
135
+ def change_internal_after_update_id; @internal_after_update_id = 102; end
136
+ def change_internal_after_destroy_id; @internal_after_destroy_id = 103; end
137
+ end
138
+ end # }}}
139
139
 
140
140
  describe "method hooks" do
141
141
  before do # {{{
142
- User.before_save :change_internal_save_id
143
- User.before_update :change_internal_update_id
144
- User.before_create :change_internal_create_id
145
- User.before_destroy :change_internal_destroy_id
146
-
147
- User.after_save :change_internal_after_save_id
148
- User.after_update :change_internal_after_update_id
149
- User.after_create :change_internal_after_create_id
150
- User.after_destroy :change_internal_after_destroy_id
142
+ Foo::User.before_save :change_internal_save_id
143
+ Foo::User.before_update :change_internal_update_id
144
+ Foo::User.before_create :change_internal_create_id
145
+ Foo::User.before_destroy :change_internal_destroy_id
146
+
147
+ Foo::User.after_save :change_internal_after_save_id
148
+ Foo::User.after_update :change_internal_after_update_id
149
+ Foo::User.after_create :change_internal_after_create_id
150
+ Foo::User.after_destroy :change_internal_after_destroy_id
151
151
  end # }}}
152
152
 
153
153
  it "perform “before save” “before create” method hook on Model#save without an ID" do # {{{
154
- @user = User.new(:fullname => "Tobias Fünke")
154
+ @user = Foo::User.new(:fullname => "Tobias Fünke")
155
155
  @user.save
156
156
  @user.internal_save_id.should == 100
157
157
  @user.internal_create_id.should == 101
@@ -159,7 +159,7 @@ describe Her::Model::Hooks do
159
159
  end # }}}
160
160
 
161
161
  it "perform “before save” and “before update” method hook on Model#save with an ID" do # {{{
162
- @user = User.find(1)
162
+ @user = Foo::User.find(1)
163
163
  @user.save
164
164
  @user.internal_save_id.should == 100
165
165
  @user.internal_create_id.should == nil
@@ -167,7 +167,7 @@ describe Her::Model::Hooks do
167
167
  end # }}}
168
168
 
169
169
  it "perform “before destroy” method hook on Model#destroy" do # {{{
170
- @user = User.find(1)
170
+ @user = Foo::User.find(1)
171
171
  @user.destroy
172
172
  @user.internal_save_id.should == nil
173
173
  @user.internal_create_id.should == nil
@@ -176,7 +176,7 @@ describe Her::Model::Hooks do
176
176
  end # }}}
177
177
 
178
178
  it "perform “after save” “after create” method hook on Model#save without an ID" do # {{{
179
- @user = User.new(:fullname => "Tobias Fünke")
179
+ @user = Foo::User.new(:fullname => "Tobias Fünke")
180
180
  @user.save
181
181
  @user.internal_after_save_id.should == 100
182
182
  @user.internal_after_create_id.should == 101
@@ -184,7 +184,7 @@ describe Her::Model::Hooks do
184
184
  end # }}}
185
185
 
186
186
  it "perform “after save” “after update” method hook on Model#save with an ID" do # {{{
187
- @user = User.find(1)
187
+ @user = Foo::User.find(1)
188
188
  @user.save
189
189
  @user.internal_after_save_id.should == 100
190
190
  @user.internal_after_create_id.should == nil
@@ -192,14 +192,14 @@ describe Her::Model::Hooks do
192
192
  end # }}}
193
193
 
194
194
  it "perform “after save” “after update” method hook on Model.save_existing" do # {{{
195
- @user = User.save_existing(1, { :fullname => "Tobias Fünke" })
195
+ @user = Foo::User.save_existing(1, { :fullname => "Tobias Fünke" })
196
196
  @user.internal_after_save_id.should == 100
197
197
  @user.internal_after_create_id.should == nil
198
198
  @user.internal_after_update_id.should == 102
199
199
  end # }}}
200
200
 
201
201
  it "perform “after save” “after create” method hook on Model.create" do # {{{
202
- @user = User.create({ :fullname => "Tobias Fünke" })
202
+ @user = Foo::User.create({ :fullname => "Tobias Fünke" })
203
203
  @user.internal_after_save_id.should == 100
204
204
  @user.internal_after_create_id.should == 101
205
205
  @user.internal_after_update_id.should == nil
@@ -208,19 +208,19 @@ describe Her::Model::Hooks do
208
208
 
209
209
  describe "block hooks" do
210
210
  before do # {{{
211
- User.before_save { |record| record.internal_save_id = 200 }
212
- User.before_create { |record| record.internal_create_id = 201 }
213
- User.before_update { |record| record.internal_update_id = 202 }
214
- User.before_destroy { |record| record.internal_destroy_id = 203 }
215
-
216
- User.after_save { |record| record.internal_after_save_id = 200 }
217
- User.after_create { |record| record.internal_after_create_id = 201 }
218
- User.after_update { |record| record.internal_after_update_id = 202 }
219
- User.after_destroy { |record| record.internal_after_destroy_id = 203 }
211
+ Foo::User.before_save { |record| record.internal_save_id = 200 }
212
+ Foo::User.before_create { |record| record.internal_create_id = 201 }
213
+ Foo::User.before_update { |record| record.internal_update_id = 202 }
214
+ Foo::User.before_destroy { |record| record.internal_destroy_id = 203 }
215
+
216
+ Foo::User.after_save { |record| record.internal_after_save_id = 200 }
217
+ Foo::User.after_create { |record| record.internal_after_create_id = 201 }
218
+ Foo::User.after_update { |record| record.internal_after_update_id = 202 }
219
+ Foo::User.after_destroy { |record| record.internal_after_destroy_id = 203 }
220
220
  end # }}}
221
221
 
222
222
  it "perform “before save” and “before create” block hook on Model#save without an ID" do # {{{
223
- @user = User.new(:fullname => "Tobias Fünke")
223
+ @user = Foo::User.new(:fullname => "Tobias Fünke")
224
224
  @user.save
225
225
  @user.internal_save_id.should == 200
226
226
  @user.internal_create_id.should == 201
@@ -228,7 +228,7 @@ describe Her::Model::Hooks do
228
228
  end # }}}
229
229
 
230
230
  it "perform “before save” and “before update” block hook on Model#save with an ID" do # {{{
231
- @user = User.find(1)
231
+ @user = Foo::User.find(1)
232
232
  @user.save
233
233
  @user.internal_save_id.should == 200
234
234
  @user.internal_create_id.should == nil
@@ -236,7 +236,7 @@ describe Her::Model::Hooks do
236
236
  end # }}}
237
237
 
238
238
  it "perform “before destroy” block hook on Model#destroy" do # {{{
239
- @user = User.find(1)
239
+ @user = Foo::User.find(1)
240
240
  @user.destroy
241
241
  @user.internal_save_id.should == nil
242
242
  @user.internal_create_id.should == nil
@@ -245,7 +245,7 @@ describe Her::Model::Hooks do
245
245
  end # }}}
246
246
 
247
247
  it "perform “after save” “after create” block hook on Model#save without an ID" do # {{{
248
- @user = User.new(:fullname => "Tobias Fünke")
248
+ @user = Foo::User.new(:fullname => "Tobias Fünke")
249
249
  @user.save
250
250
  @user.internal_after_save_id.should == 200
251
251
  @user.internal_after_create_id.should == 201
@@ -253,7 +253,7 @@ describe Her::Model::Hooks do
253
253
  end # }}}
254
254
 
255
255
  it "perform “after save” “after update” block hook on Model#save with an ID" do # {{{
256
- @user = User.find(1)
256
+ @user = Foo::User.find(1)
257
257
  @user.save
258
258
  @user.internal_after_save_id.should == 200
259
259
  @user.internal_after_create_id.should == nil