her 0.2.6 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
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