activeresource 4.1.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +5 -5
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +324 -0
  4. data/lib/active_resource/active_job_serializer.rb +26 -0
  5. data/lib/active_resource/associations/builder/association.rb +6 -6
  6. data/lib/active_resource/associations/builder/belongs_to.rb +5 -3
  7. data/lib/active_resource/associations/builder/has_many.rb +4 -2
  8. data/lib/active_resource/associations/builder/has_one.rb +5 -3
  9. data/lib/active_resource/associations.rb +23 -20
  10. data/lib/active_resource/base.rb +233 -113
  11. data/lib/active_resource/callbacks.rb +3 -1
  12. data/lib/active_resource/collection.rb +21 -12
  13. data/lib/active_resource/connection.rb +78 -81
  14. data/lib/active_resource/custom_methods.rb +8 -6
  15. data/lib/active_resource/exceptions.rb +17 -5
  16. data/lib/active_resource/formats/json_format.rb +4 -1
  17. data/lib/active_resource/formats/xml_format.rb +4 -2
  18. data/lib/active_resource/formats.rb +5 -3
  19. data/lib/active_resource/http_mock.rb +23 -27
  20. data/lib/active_resource/inheriting_hash.rb +15 -0
  21. data/lib/active_resource/log_subscriber.rb +14 -3
  22. data/lib/active_resource/railtie.rb +10 -10
  23. data/lib/active_resource/reflection.rb +11 -10
  24. data/lib/active_resource/schema.rb +6 -3
  25. data/lib/active_resource/singleton.rb +25 -28
  26. data/lib/active_resource/threadsafe_attributes.rb +35 -31
  27. data/lib/active_resource/validations.rb +18 -15
  28. data/lib/active_resource/version.rb +6 -4
  29. data/lib/active_resource.rb +8 -7
  30. data/lib/activeresource.rb +3 -1
  31. metadata +41 -24
  32. data/README.rdoc +0 -231
  33. data/lib/active_resource/observing.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5ec4c5f35bfca437beeae8e7acb8763bc0ce1f96
4
- data.tar.gz: 9ce68f2e6a206530f05c57ce23aaa0f240bc74f8
2
+ SHA256:
3
+ metadata.gz: f2a0c925e2619c4a4204eebdaea70776a57fec944e9eefeb98982ed8cf425bbc
4
+ data.tar.gz: b77c66a74c3fe0d32e16d0ce4eaaec1c772200bda9ea36b2bfba1a3cc4f58b5d
5
5
  SHA512:
6
- metadata.gz: e8faca6d64850e4eb46e54d829c90355b7d18538b618032498e747dd27fc12861fac7e5e0d5ba53f4bf7eb7203f85c2dd092f0ad1a3badc3ed290a958558e820
7
- data.tar.gz: 23fd61de41602794182b27df1703ae3e7a82dba3249c285524f6a5d681b792b9ea38ab782d1a4731b8ddf7a09eb3b78acf5ce0ea04cca8bf0f2d573129da1a9f
6
+ metadata.gz: 9116078833a262f5a4d184a9cd080f3a29bfc5c07481cf352dd87baa735ba0dfae6159a35ac37ea1ad2e121348a33d958151a048af8dbb6e85e3a387076de3b5
7
+ data.tar.gz: 02e8b7e3aa1fd89f70f67b2696d778bf0c4a5d89c4b6f779ec3ecffc6a099374c06515ec2bfcb4e7175a518f00543f16b1b691670378c2533fcf353ce82cb96f
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2016 David Heinemeier Hansson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,324 @@
1
+ # Active Resource
2
+
3
+ Active Resource (ARes) connects business objects and Representational State Transfer (REST)
4
+ web services. It implements object-relational mapping for REST web services to provide transparent
5
+ proxying capabilities between a client (Active Resource) and a RESTful service (which is provided by
6
+ Simply RESTful routing in `ActionController::Resources`).
7
+
8
+ ## Philosophy
9
+
10
+ Active Resource attempts to provide a coherent wrapper object-relational mapping for REST
11
+ web services. It follows the same philosophy as Active Record, in that one of its prime aims
12
+ is to reduce the amount of code needed to map to these resources. This is made possible
13
+ by relying on a number of code- and protocol-based conventions that make it easy for Active Resource
14
+ to infer complex relations and structures. These conventions are outlined in detail in the documentation
15
+ for `ActiveResource::Base`.
16
+
17
+ ## Overview
18
+
19
+ Model classes are mapped to remote REST resources by Active Resource much the same way Active Record maps
20
+ model classes to database tables. When a request is made to a remote resource, a REST JSON request is
21
+ generated, transmitted, and the result received and serialized into a usable Ruby object.
22
+
23
+ ## Download and installation
24
+
25
+ The latest version of Active Resource can be installed with RubyGems:
26
+
27
+ ```
28
+ gem install activeresource
29
+ ```
30
+
31
+ Or added to a Gemfile:
32
+
33
+ ```ruby
34
+ gem 'activeresource'
35
+ ```
36
+
37
+ Source code can be downloaded on GitHub
38
+
39
+ * https://github.com/rails/activeresource/tree/main
40
+
41
+ ### Configuration and Usage
42
+
43
+ Putting Active Resource to use is very similar to Active Record. It's as simple as creating a model class
44
+ that inherits from `ActiveResource::Base` and providing a `site` class variable to it:
45
+
46
+ ```ruby
47
+ class Person < ActiveResource::Base
48
+ self.site = "http://api.people.com:3000"
49
+ end
50
+ ```
51
+
52
+ Now the Person class is REST enabled and can invoke REST services very similarly to how Active Record invokes
53
+ life cycle methods that operate against a persistent store.
54
+
55
+ ```ruby
56
+ # Find a person with id = 1
57
+ tyler = Person.find(1)
58
+ Person.exists?(1) # => true
59
+ ```
60
+
61
+ As you can see, the methods are quite similar to Active Record's methods for dealing with database
62
+ records. But rather than dealing directly with a database record, you're dealing with HTTP resources
63
+ (which may or may not be database records).
64
+
65
+ Connection settings (`site`, `headers`, `user`, `password`, `bearer_token`, `proxy`) and the connections
66
+ themselves are store in thread-local variables to make them thread-safe, so you can also set these
67
+ dynamically, even in a multi-threaded environment, for instance:
68
+
69
+ ```ruby
70
+ ActiveResource::Base.site = api_site_for(request)
71
+ ```
72
+ ### Authentication
73
+
74
+ Active Resource supports the token based authentication provided by Rails through the
75
+ `ActionController::HttpAuthentication::Token` class using custom headers.
76
+
77
+ ```ruby
78
+ class Person < ActiveResource::Base
79
+ self.headers['Authorization'] = 'Token token="abcd"'
80
+ end
81
+ ```
82
+
83
+ You can also set any specific HTTP header using the same way. As mentioned above, headers are
84
+ thread-safe, so you can set headers dynamically, even in a multi-threaded environment:
85
+
86
+ ```ruby
87
+ ActiveResource::Base.headers['Authorization'] = current_session_api_token
88
+ ```
89
+
90
+ Active Resource supports 2 options for HTTP authentication today.
91
+
92
+ 1. Basic
93
+ ```ruby
94
+ class Person < ActiveResource::Base
95
+ self.user = 'my@email.com'
96
+ self.password = '123'
97
+ end
98
+ # username: my@email.com password: 123
99
+ ```
100
+
101
+ 2. Bearer Token
102
+ ```ruby
103
+ class Person < ActiveResource::Base
104
+ self.auth_type = :bearer
105
+ self.bearer_token = 'my-token123'
106
+ end
107
+ # Bearer my-token123
108
+ ```
109
+
110
+ ### Protocol
111
+
112
+ Active Resource is built on a standard JSON or XML format for requesting and submitting resources
113
+ over HTTP. It mirrors the RESTful routing built into Action Controller but will also work with any
114
+ other REST service that properly implements the protocol. REST uses HTTP, but unlike "typical" web
115
+ applications, it makes use of all the verubys available in the HTTP specification:
116
+
117
+ * GET requests are used for finding and retrieving resources.
118
+ * POST requests are used to create new resources.
119
+ * PUT requests are used to update existing resources.
120
+ * DELETE requests are used to delete resources.
121
+
122
+ For more information on how this protocol works with Active Resource, see the `ActiveResource::Base` documentation;
123
+ for more general information on REST web services, see the article
124
+ [here](http://en.wikipedia.org/wiki/Representational_State_Transfer).
125
+
126
+ ### Find
127
+
128
+ Find requests use the GET method and expect the JSON form of whatever resource/resources is/are
129
+ being requested. So, for a request for a single element, the JSON of that item is expected in
130
+ response:
131
+
132
+ ```ruby
133
+ # Expects a response of
134
+ #
135
+ # {"id":1,"first":"Tyler","last":"Durden"}
136
+ #
137
+ # for GET http://api.people.com:3000/people/1.json
138
+ #
139
+ tyler = Person.find(1)
140
+ ```
141
+
142
+ The JSON document that is received is used to build a new object of type Person, with each
143
+ JSON element becoming an attribute on the object.
144
+
145
+ ```ruby
146
+ tyler.is_a? Person # => true
147
+ tyler.last # => 'Durden'
148
+ ```
149
+
150
+ Any complex element (one that contains other elements) becomes its own object:
151
+
152
+ ```ruby
153
+ # With this response:
154
+ # {"id":1,"first":"Tyler","address":{"street":"Paper St.","state":"CA"}}
155
+ #
156
+ # for GET http://api.people.com:3000/people/1.json
157
+ #
158
+ tyler = Person.find(1)
159
+ tyler.address # => <Person::Address::xxxxx>
160
+ tyler.address.street # => 'Paper St.'
161
+ ```
162
+
163
+ Collections can also be requested in a similar fashion
164
+
165
+ ```ruby
166
+ # Expects a response of
167
+ #
168
+ # [
169
+ # {"id":1,"first":"Tyler","last":"Durden"},
170
+ # {"id":2,"first":"Tony","last":"Stark",}
171
+ # ]
172
+ #
173
+ # for GET http://api.people.com:3000/people.json
174
+ #
175
+ people = Person.all
176
+ people.first # => <Person::xxx 'first' => 'Tyler' ...>
177
+ people.last # => <Person::xxx 'first' => 'Tony' ...>
178
+ ```
179
+
180
+ ### Create
181
+
182
+ Creating a new resource submits the JSON form of the resource as the body of the request and expects
183
+ a 'Location' header in the response with the RESTful URL location of the newly created resource. The
184
+ id of the newly created resource is parsed out of the Location response header and automatically set
185
+ as the id of the ARes object.
186
+
187
+ ```ruby
188
+ # {"first":"Tyler","last":"Durden"}
189
+ #
190
+ # is submitted as the body on
191
+ #
192
+ # if include_root_in_json is not set or set to false => {"first":"Tyler"}
193
+ # if include_root_in_json is set to true => {"person":{"first":"Tyler"}}
194
+ #
195
+ # POST http://api.people.com:3000/people.json
196
+ #
197
+ # when save is called on a new Person object. An empty response is
198
+ # is expected with a 'Location' header value:
199
+ #
200
+ # Response (201): Location: http://api.people.com:3000/people/2
201
+ #
202
+ tyler = Person.new(:first => 'Tyler')
203
+ tyler.new? # => true
204
+ tyler.save # => true
205
+ tyler.new? # => false
206
+ tyler.id # => 2
207
+ ```
208
+
209
+ ### Update
210
+
211
+ 'save' is also used to update an existing resource and follows the same protocol as creating a resource
212
+ with the exception that no response headers are needed -- just an empty response when the update on the
213
+ server side was successful.
214
+
215
+ ```ruby
216
+ # {"first":"Tyler"}
217
+ #
218
+ # is submitted as the body on
219
+ #
220
+ # if include_root_in_json is not set or set to false => {"first":"Tyler"}
221
+ # if include_root_in_json is set to true => {"person":{"first":"Tyler"}}
222
+ #
223
+ # PUT http://api.people.com:3000/people/1.json
224
+ #
225
+ # when save is called on an existing Person object. An empty response is
226
+ # is expected with code (204)
227
+ #
228
+ tyler = Person.find(1)
229
+ tyler.first # => 'Tyler'
230
+ tyler.first = 'Tyson'
231
+ tyler.save # => true
232
+ ```
233
+
234
+ ### Delete
235
+
236
+ Destruction of a resource can be invoked as a class and instance method of the resource.
237
+
238
+ ```ruby
239
+ # A request is made to
240
+ #
241
+ # DELETE http://api.people.com:3000/people/1.json
242
+ #
243
+ # for both of these forms. An empty response with
244
+ # is expected with response code (200)
245
+ #
246
+ tyler = Person.find(1)
247
+ tyler.destroy # => true
248
+ tyler.exists? # => false
249
+ Person.delete(2) # => true
250
+ Person.exists?(2) # => false
251
+ ```
252
+
253
+ ### Associations
254
+
255
+ Relationships between resources can be declared using the standard association syntax
256
+ that should be familiar to anyone who uses Active Record. For example, using the
257
+ class definition below:
258
+
259
+ ```ruby
260
+ class Post < ActiveResource::Base
261
+ self.site = "http://blog.io"
262
+ has_many :comments
263
+ end
264
+
265
+ post = Post.find(1) # issues GET http://blog.io/posts/1.json
266
+ comments = post.comments # issues GET http://blog.io/comments.json?post_id=1
267
+ ```
268
+
269
+ In this case, the `Comment` model would have to be implemented as Active Resource, too.
270
+
271
+ If you control the server, you may wish to include nested resources thus avoiding a
272
+ second network request. Given the resource above, if the response includes comments
273
+ in the response, they will be automatically loaded into the Active Resource object.
274
+ The server-side model can be adjusted as follows to include comments in the response.
275
+
276
+ ```ruby
277
+ class Post < ActiveRecord::Base
278
+ has_many :comments
279
+
280
+ def as_json(options)
281
+ super.merge(:include=>[:comments])
282
+ end
283
+ end
284
+ ```
285
+
286
+ ### Logging
287
+
288
+ Active Resource instruments the event `request.active_resource` when doing a request
289
+ to the remote service. You can subscribe to it by doing:
290
+
291
+ ```ruby
292
+ ActiveSupport::Notifications.subscribe('request.active_resource') do |name, start, finish, id, payload|
293
+ ```
294
+
295
+ The `payload` is a `Hash` with the following keys:
296
+
297
+ * `method` as a `Symbol`
298
+ * `request_uri` as a `String`
299
+ * `result` as an `Net::HTTPResponse`
300
+
301
+ ## License
302
+
303
+ Active Resource is released under the MIT license:
304
+
305
+ * http://www.opensource.org/licenses/MIT
306
+
307
+ ## Contributing to Active Resource
308
+
309
+ Active Resource is work of many contributors. You're encouraged to submit pull requests, propose
310
+ features and discuss issues.
311
+
312
+ See [CONTRIBUTING](https://github.com/rails/activeresource/blob/main/CONTRIBUTING.md).
313
+
314
+ ## Support
315
+
316
+ Full API documentation is available at
317
+
318
+ * http://rubydoc.info/gems/activeresource
319
+
320
+ Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
321
+
322
+ * https://github.com/rails/activeresource/issues
323
+
324
+ You can find more usage information in the ActiveResource::Base documentation.
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveResource
4
+ class ActiveJobSerializer < ActiveJob::Serializers::ObjectSerializer
5
+ def serialize(resource)
6
+ super(
7
+ "class" => resource.class.name,
8
+ "persisted" => resource.persisted?,
9
+ "prefix_options" => resource.prefix_options.as_json,
10
+ "attributes" => resource.attributes.as_json
11
+ )
12
+ end
13
+
14
+ def deserialize(hash)
15
+ hash["class"].constantize.new(hash["attributes"]).tap do |resource|
16
+ resource.persisted = hash["persisted"]
17
+ resource.prefix_options = hash["prefix_options"]
18
+ end
19
+ end
20
+
21
+ private
22
+ def klass
23
+ ActiveResource::Base
24
+ end
25
+ end
26
+ end
@@ -1,6 +1,7 @@
1
- module ActiveResource::Associations::Builder
2
- class Association #:nodoc:
1
+ # frozen_string_literal: true
3
2
 
3
+ module ActiveResource::Associations::Builder
4
+ class Association # :nodoc:
4
5
  # providing a Class-Variable, which will have a different store of subclasses
5
6
  class_attribute :valid_options
6
7
  self.valid_options = [:class_name]
@@ -24,9 +25,8 @@ module ActiveResource::Associations::Builder
24
25
  end
25
26
 
26
27
  private
27
-
28
- def validate_options
29
- options.assert_valid_keys(self.class.valid_options)
30
- end
28
+ def validate_options
29
+ options.assert_valid_keys(self.class.valid_options)
30
+ end
31
31
  end
32
32
  end
@@ -1,4 +1,6 @@
1
- module ActiveResource::Associations::Builder
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveResource::Associations::Builder
2
4
  class BelongsTo < Association
3
5
  self.valid_options += [:foreign_key]
4
6
 
@@ -7,8 +9,8 @@ module ActiveResource::Associations::Builder
7
9
  def build
8
10
  validate_options
9
11
  reflection = model.create_reflection(self.class.macro, name, options)
10
- model.defines_belongs_to_finder_method(reflection.name, reflection.klass, reflection.foreign_key)
11
- return reflection
12
+ model.defines_belongs_to_finder_method(reflection)
13
+ reflection
12
14
  end
13
15
  end
14
16
  end
@@ -1,11 +1,13 @@
1
- module ActiveResource::Associations::Builder
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveResource::Associations::Builder
2
4
  class HasMany < Association
3
5
  self.macro = :has_many
4
6
 
5
7
  def build
6
8
  validate_options
7
9
  model.create_reflection(self.class.macro, name, options).tap do |reflection|
8
- model.defines_has_many_finder_method(reflection.name, reflection.klass)
10
+ model.defines_has_many_finder_method(reflection)
9
11
  end
10
12
  end
11
13
  end
@@ -1,11 +1,13 @@
1
- module ActiveResource::Associations::Builder
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveResource::Associations::Builder
2
4
  class HasOne < Association
3
5
  self.macro = :has_one
4
-
6
+
5
7
  def build
6
8
  validate_options
7
9
  model.create_reflection(self.class.macro, name, options).tap do |reflection|
8
- model.defines_has_one_finder_method(reflection.name, reflection.klass)
10
+ model.defines_has_one_finder_method(reflection)
9
11
  end
10
12
  end
11
13
  end
@@ -1,10 +1,11 @@
1
- module ActiveResource::Associations
1
+ # frozen_string_literal: true
2
2
 
3
+ module ActiveResource::Associations
3
4
  module Builder
4
- autoload :Association, 'active_resource/associations/builder/association'
5
- autoload :HasMany, 'active_resource/associations/builder/has_many'
6
- autoload :HasOne, 'active_resource/associations/builder/has_one'
7
- autoload :BelongsTo, 'active_resource/associations/builder/belongs_to'
5
+ autoload :Association, "active_resource/associations/builder/association"
6
+ autoload :HasMany, "active_resource/associations/builder/has_many"
7
+ autoload :HasOne, "active_resource/associations/builder/has_one"
8
+ autoload :BelongsTo, "active_resource/associations/builder/belongs_to"
8
9
  end
9
10
 
10
11
 
@@ -65,7 +66,7 @@ module ActiveResource::Associations
65
66
  # Would resolve this author into the <tt>Myblog::Author</tt> class.
66
67
  #
67
68
  # If the response body does not contain an attribute matching the association name
68
- # a request is sent to a singelton path under the current resource.
69
+ # a request is sent to a singleton path under the current resource.
69
70
  # For example, if a Product class <tt>has_one :inventory</tt> calling <tt>Product#inventory</tt>
70
71
  # will generate a request on /products/:product_id/inventory.json.
71
72
  #
@@ -89,15 +90,15 @@ module ActiveResource::Associations
89
90
  #
90
91
  # === Example
91
92
  #
92
- # A Comment class declaress <tt>belongs_to :post</tt>, which will add:
93
+ # A Comment class declares <tt>belongs_to :post</tt>, which will add:
93
94
  # * <tt>Comment#post</tt> (similar to <tt>Post.find(post_id)</tt>)
94
95
  # The declaration can also include an options hash to specialize the behavior of the association.
95
96
  #
96
97
  # === Options
97
98
  # [:class_name]
98
- # Specify the class name for the association. Use it only if that name canÄt be inferred from association name.
99
+ # Specify the class name for the association. Use it only if that name can't be inferred from association name.
99
100
  # So <tt>belongs_to :post</tt> will by default be linked to the Post class, but if the real class name is Article,
100
- # you'll have to specify it with whis option.
101
+ # you'll have to specify it with this option.
101
102
  # [:foreign_key]
102
103
  # Specify the foreign key used for the association. By default this is guessed to be the name
103
104
  # of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :post</tt>
@@ -112,12 +113,13 @@ module ActiveResource::Associations
112
113
  # <tt>belongs_to :customer, :foreign_key => 'user_id'</tt>
113
114
  # Creates a belongs_to association called customer which would be resolved by the foreign_key <tt>user_id</tt> instead of <tt>customer_id</tt>
114
115
  #
115
- def belongs_to(name, options={})
116
+ def belongs_to(name, options = {})
116
117
  Builder::BelongsTo.build(self, name, options)
117
118
  end
118
119
 
119
120
  # Defines the belongs_to association finder method
120
- def defines_belongs_to_finder_method(method_name, association_model, finder_key)
121
+ def defines_belongs_to_finder_method(reflection)
122
+ method_name = reflection.name
121
123
  ivar_name = :"@#{method_name}"
122
124
 
123
125
  if method_defined?(method_name)
@@ -130,13 +132,14 @@ module ActiveResource::Associations
130
132
  instance_variable_get(ivar_name)
131
133
  elsif attributes.include?(method_name)
132
134
  attributes[method_name]
133
- elsif association_id = send(finder_key)
134
- instance_variable_set(ivar_name, association_model.find(association_id))
135
+ elsif association_id = send(reflection.foreign_key)
136
+ instance_variable_set(ivar_name, reflection.klass.find(association_id))
135
137
  end
136
138
  end
137
139
  end
138
140
 
139
- def defines_has_many_finder_method(method_name, association_model)
141
+ def defines_has_many_finder_method(reflection)
142
+ method_name = reflection.name
140
143
  ivar_name = :"@#{method_name}"
141
144
 
142
145
  define_method(method_name) do
@@ -145,7 +148,7 @@ module ActiveResource::Associations
145
148
  elsif attributes.include?(method_name)
146
149
  attributes[method_name]
147
150
  elsif !new_record?
148
- instance_variable_set(ivar_name, association_model.find(:all, :params => {:"#{self.class.element_name}_id" => self.id}))
151
+ instance_variable_set(ivar_name, reflection.klass.find(:all, params: { "#{self.class.element_name}_id": self.id }))
149
152
  else
150
153
  instance_variable_set(ivar_name, self.class.collection_parser.new)
151
154
  end
@@ -153,7 +156,8 @@ module ActiveResource::Associations
153
156
  end
154
157
 
155
158
  # Defines the has_one association
156
- def defines_has_one_finder_method(method_name, association_model)
159
+ def defines_has_one_finder_method(reflection)
160
+ method_name = reflection.name
157
161
  ivar_name = :"@#{method_name}"
158
162
 
159
163
  define_method(method_name) do
@@ -161,12 +165,11 @@ module ActiveResource::Associations
161
165
  instance_variable_get(ivar_name)
162
166
  elsif attributes.include?(method_name)
163
167
  attributes[method_name]
164
- elsif association_model.respond_to?(:singleton_name)
165
- instance_variable_set(ivar_name, association_model.find(:params => {:"#{self.class.element_name}_id" => self.id}))
168
+ elsif reflection.klass.respond_to?(:singleton_name)
169
+ instance_variable_set(ivar_name, reflection.klass.find(params: { "#{self.class.element_name}_id": self.id }))
166
170
  else
167
- instance_variable_set(ivar_name, association_model.find(:one, :from => "/#{self.class.collection_name}/#{self.id}/#{method_name}#{self.class.format_extension}"))
171
+ instance_variable_set(ivar_name, reflection.klass.find(:one, from: "/#{self.class.collection_name}/#{self.id}/#{method_name}#{self.class.format_extension}"))
168
172
  end
169
173
  end
170
174
  end
171
-
172
175
  end