activeresource 4.1.0 → 6.0.0

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.
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