reactive_resource 0.6.1 → 0.7.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.
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - rbx-18mode
7
+ - rbx-19mode
8
+ env:
9
+ - RAILS_VERSION=3.1.0
10
+ - RAILS_VERSION=3.2.0
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source :rubygems
2
2
 
3
3
  # Specify your gem's dependencies in reactive_resource.gemspec
4
4
  gemspec
data/Gemfile.lock CHANGED
@@ -1,25 +1,28 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reactive_resource (0.6.0)
5
- activeresource (>= 2.3.10)
4
+ reactive_resource (0.7.0)
5
+ activeresource (>= 3.1)
6
+ activesupport (>= 3.1)
6
7
 
7
8
  GEM
8
9
  remote: http://rubygems.org/
9
10
  specs:
10
- activemodel (3.0.6)
11
- activesupport (= 3.0.6)
12
- builder (~> 2.1.2)
13
- i18n (~> 0.5.0)
14
- activeresource (3.0.6)
15
- activemodel (= 3.0.6)
16
- activesupport (= 3.0.6)
17
- activesupport (3.0.6)
11
+ activemodel (3.2.2)
12
+ activesupport (= 3.2.2)
13
+ builder (~> 3.0.0)
14
+ activeresource (3.2.2)
15
+ activemodel (= 3.2.2)
16
+ activesupport (= 3.2.2)
17
+ activesupport (3.2.2)
18
+ i18n (~> 0.6)
19
+ multi_json (~> 1.0)
18
20
  addressable (2.2.2)
19
- builder (2.1.2)
21
+ builder (3.0.0)
20
22
  crack (0.1.8)
21
- i18n (0.5.0)
22
- rake (0.8.7)
23
+ i18n (0.6.0)
24
+ multi_json (1.1.0)
25
+ rake (0.9.2)
23
26
  shoulda (2.11.3)
24
27
  webmock (1.6.2)
25
28
  addressable (>= 2.2.2)
@@ -1,7 +1,8 @@
1
1
  require 'active_resource'
2
+ require 'active_support/all'
2
3
 
3
4
  module ReactiveResource
4
-
5
+
5
6
  # The class that all ReactiveResourse resources should inherit
6
7
  # from. This class fixes and patches over a lot of the broken stuff
7
8
  # in Active Resource, and smoothes out the differences between the
@@ -9,21 +10,23 @@ module ReactiveResource
9
10
  # It also adds support for ActiveRecord-like associations.
10
11
  class Base < ActiveResource::Base
11
12
  extend Extensions::RelativeConstGet
13
+ class_attribute :singleton_resource
14
+
12
15
  # Call this method to transform a resource into a 'singleton'
13
16
  # resource. This will fix the paths Active Resource generates for
14
17
  # singleton resources. See
15
18
  # https://rails.lighthouseapp.com/projects/8994/tickets/4348-supporting-singleton-resources-in-activeresource
16
19
  # for more info.
17
20
  def self.singleton
18
- write_inheritable_attribute(:singleton, true)
21
+ self.singleton_resource = true
19
22
  end
20
23
 
21
24
  # +true+ if this resource is a singleton resource, +false+
22
25
  # otherwise
23
26
  def self.singleton?
24
- read_inheritable_attribute(:singleton)
27
+ self.singleton_resource?
25
28
  end
26
-
29
+
27
30
  # Active Resource's find_one does nothing if you don't pass a
28
31
  # +:from+ parameter. This doesn't make sense if you're dealing
29
32
  # with a singleton resource, so if we don't get anything back from
@@ -33,11 +36,11 @@ module ReactiveResource
33
36
  if !found_object && singleton?
34
37
  prefix_options, query_options = split_options(options[:params])
35
38
  path = element_path(nil, prefix_options, query_options)
36
- found_object = instantiate_record(connection.get(path, headers), prefix_options)
39
+ found_object = instantiate_record(format.decode(connection.get(path, headers).body), prefix_options)
37
40
  end
38
41
  found_object
39
42
  end
40
-
43
+
41
44
  # Override ActiveResource's +collection_name+ to support singular
42
45
  # names for singleton resources.
43
46
  def self.collection_name
@@ -75,7 +78,7 @@ module ReactiveResource
75
78
  def self.element_path(id, prefix_options = {}, query_options = nil)
76
79
  prefix_options, query_options = split_options(prefix_options) if query_options.nil?
77
80
  element_path = "#{prefix(prefix_options)}#{association_prefix(prefix_options)}#{collection_name}"
78
-
81
+
79
82
  # singleton resources don't have an ID
80
83
  if id || !singleton?
81
84
  element_path += "/#{id}"
@@ -88,7 +91,7 @@ module ReactiveResource
88
91
  # keys corresponding to the belongs_to associations (since they'll
89
92
  # be in the URL anyway), so we'll try to inject them based on the
90
93
  # attributes of the object we just used.
91
- def load(attributes)
94
+ def load(attributes, remove_root=false)
92
95
  attributes = attributes.stringify_keys
93
96
  self.class.belongs_to_with_parents.each do |belongs_to_param|
94
97
  attributes["#{belongs_to_param}_id"] ||= prefix_options["#{belongs_to_param}_id".intern]
@@ -98,7 +101,7 @@ module ReactiveResource
98
101
  # even if we aren't actually using the association.
99
102
  @attributes["#{belongs_to_param}_id"] = attributes["#{belongs_to_param}_id"]
100
103
  end
101
- super(attributes)
104
+ super(attributes, remove_root)
102
105
  end
103
106
 
104
107
  # Add all of the belongs_to attributes as prefix parameters. This is
@@ -121,7 +124,7 @@ module ReactiveResource
121
124
  options = options.dup
122
125
  used_associations = []
123
126
  parent_associations = []
124
-
127
+
125
128
  # Recurse to add the parent resource hierarchy. For Phone, for
126
129
  # instance, this will add the '/lawyers/:id' part of the URL,
127
130
  # which it knows about from the Address class.
@@ -132,7 +135,7 @@ module ReactiveResource
132
135
 
133
136
  # The association chain we're following
134
137
  used_association = nil
135
-
138
+
136
139
  belongs_to_associations.each do |association|
137
140
  if !used_association && param_value = options.delete("#{association.attribute}_id".intern) # only take the first one
138
141
  used_associations << association
@@ -150,11 +153,11 @@ module ReactiveResource
150
153
  def self.association_prefix(options)
151
154
  options = options.dup
152
155
  association_prefix = ''
153
-
156
+
154
157
  if belongs_to_associations
155
158
 
156
159
  used_associations = prefix_associations(options)
157
-
160
+
158
161
  association_prefix = used_associations.map do |association|
159
162
  collection_name = association.associated_class.collection_name
160
163
  value = options.delete("#{association.attribute}_id".intern)
@@ -172,7 +175,7 @@ module ReactiveResource
172
175
  attr_accessor :associations
173
176
  end
174
177
  self.associations = []
175
-
178
+
176
179
  # Add a has_one relationship to another class. +options+ is a hash
177
180
  # of extra parameters:
178
181
  #
@@ -182,7 +185,7 @@ module ReactiveResource
182
185
  def self.has_one(attribute, options = {})
183
186
  self.associations << Association::HasOneAssociation.new(self, attribute, options)
184
187
  end
185
-
188
+
186
189
  # Add a has_many relationship to another class. +options+ is a hash
187
190
  # of extra parameters:
188
191
  #
@@ -1,4 +1,4 @@
1
1
  module ReactiveResource
2
2
  # The current version of ReactiveResource
3
- VERSION = "0.6.1"
3
+ VERSION = "0.7.0"
4
4
  end
@@ -1,4 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ rails_version = ENV.key?('RAILS_VERSION') ? "~> #{ENV['RAILS_VERSION']}" : '>= 3.1'
2
3
  $:.push File.expand_path("../lib", __FILE__)
3
4
  require "reactive_resource/version"
4
5
 
@@ -14,10 +15,11 @@ Gem::Specification.new do |s|
14
15
 
15
16
  s.rubyforge_project = "reactive_resource"
16
17
 
17
- s.add_dependency "activeresource", '>= 2.3.10'
18
+ s.add_dependency "activeresource", rails_version
19
+ s.add_dependency "activesupport", rails_version
18
20
  s.add_development_dependency "shoulda", '~> 2.11.3'
19
21
  s.add_development_dependency "webmock", '~> 1.6.1'
20
-
22
+
21
23
  s.files = `git ls-files`.split("\n")
22
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
25
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -19,13 +19,13 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
19
19
  assert_equal ReactiveResource::Lawyer, @object.class.associations.detect {|assoc| assoc.attribute == :lawyer }.associated_class
20
20
  end
21
21
  end
22
-
22
+
23
23
  context "A resource that inherits from ReactiveResource::Base" do
24
-
24
+
25
25
  setup do
26
26
  @object = ReactiveResource::Lawyer.new
27
27
  end
28
-
28
+
29
29
  should "hit the Avvo API with the correct URL when saved" do
30
30
  stub_request(:post, "https://api.avvo.com/api/1/lawyers.json")
31
31
  @object.save
@@ -33,14 +33,16 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
33
33
  end
34
34
 
35
35
  should "hit the Avvo API with the correct URL when retrieved" do
36
- stub_request(:get, "https://api.avvo.com/api/1/lawyers/1.json").to_return(:body => {:id => '1'}.to_json)
36
+ stub_request(:get, "https://api.avvo.com/api/1/lawyers/1.json")\
37
+ .to_return(:body => {:lawyer => {:id => '1'}}.to_json)
37
38
  ReactiveResource::Lawyer.find(1)
38
39
  assert_requested(:get, "https://api.avvo.com/api/1/lawyers/1.json")
39
40
  end
40
41
 
41
42
  context "with a has_many relationship to another object" do
42
43
  should "hit the associated object's URL with the correct parameters when requested" do
43
- stub_request(:get, "https://api.avvo.com/api/1/lawyers/1/addresses.json")
44
+ stub_request(:get, "https://api.avvo.com/api/1/lawyers/1/addresses.json")\
45
+ .to_return(:body => [{:address => {:id => 1}}].to_json)
44
46
  @object.id = 1
45
47
  @object.addresses
46
48
  assert_requested(:get, "https://api.avvo.com/api/1/lawyers/1/addresses.json")
@@ -49,7 +51,8 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
49
51
 
50
52
  context "with a has_one relationship to another object" do
51
53
  should "hit the associated object's URL with the correct parameters when requested" do
52
- stub_request(:get, "https://api.avvo.com/api/1/lawyers/1/headshot.json").to_return(:body => {:headshot_url => "blah"}.to_json)
54
+ stub_request(:get, "https://api.avvo.com/api/1/lawyers/1/headshot.json")\
55
+ .to_return(:body => {:headshot => {:headshot_url => "blah"}}.to_json)
53
56
  @object.id = 1
54
57
  @object.headshot
55
58
  assert_requested(:get, "https://api.avvo.com/api/1/lawyers/1/headshot.json")
@@ -60,21 +63,23 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
60
63
  setup do
61
64
  @object = ReactiveResource::Address.new(:lawyer_id => 2)
62
65
  end
63
-
66
+
64
67
  should "hit the Avvo API with the correct URL when saved" do
65
68
  stub_request(:post, "https://api.avvo.com/api/1/lawyers/2/addresses.json")
66
69
  @object.save
67
70
  assert_requested(:post, "https://api.avvo.com/api/1/lawyers/2/addresses.json")
68
71
  end
69
-
72
+
70
73
  should "hit the Avvo API with the correct URL when retrieved" do
71
- stub_request(:get, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json").to_return(:body => {:id => '3'}.to_json)
74
+ stub_request(:get, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json")\
75
+ .to_return(:body => {:address => {:id => '3'}}.to_json)
72
76
  ReactiveResource::Address.find(3, :params => {:lawyer_id => 2})
73
- assert_requested(:get, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json")
77
+ assert_requested(:get, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json")
74
78
  end
75
79
 
76
80
  should "hit the Avvo API with the correct URL when updated" do
77
- stub_request(:get, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json").to_return(:body => {:id => '3'}.to_json)
81
+ stub_request(:get, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json")\
82
+ .to_return(:body => {:address => {:id => '3'}}.to_json)
78
83
  license = ReactiveResource::Address.find(3, :params => {:lawyer_id => 2})
79
84
  assert_requested(:get, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json")
80
85
  stub_request(:put, "https://api.avvo.com/api/1/lawyers/2/addresses/3.json")
@@ -83,7 +88,8 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
83
88
  end
84
89
 
85
90
  should "set the prefix parameters correctly when saved" do
86
- stub_request(:post, "https://api.avvo.com/api/1/lawyers/2/addresses.json").to_return(:body => {:id => '2'}.to_json)
91
+ stub_request(:post, "https://api.avvo.com/api/1/lawyers/2/addresses.json")\
92
+ .to_return(:body => {:address => {:id => '2'}}.to_json)
87
93
  @object.save
88
94
  assert_requested(:post, "https://api.avvo.com/api/1/lawyers/2/addresses.json")
89
95
 
@@ -112,7 +118,8 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
112
118
  @object.doctor_id = 2
113
119
  @object.address_id = 3
114
120
  assert_equal 3, @object.address_id
115
- stub_request(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3.json").to_return(:body => {:id => '3'}.to_json)
121
+ stub_request(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3.json")\
122
+ .to_return(:body => {:address => {:id => '3'}}.to_json)
116
123
  @object.address
117
124
  @object.address
118
125
  assert_requested(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3.json", :times => 1)
@@ -125,7 +132,8 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
125
132
  end
126
133
 
127
134
  should "hit the Avvo API with the correct URL when updated" do
128
- stub_request(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3/phones/4.json").to_return(:body => {:id => '4'}.to_json)
135
+ stub_request(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3/phones/4.json")\
136
+ .to_return(:body => {:address => {:id => '4'}}.to_json)
129
137
  phone = ReactiveResource::Phone.find(4, :params => {:doctor_id => 2, :address_id => 3})
130
138
  assert_requested(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3/phones/4.json")
131
139
 
@@ -141,9 +149,10 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
141
149
 
142
150
  assert_equal "/api/1/doctors/2/addresses/3/phones/4.json", @object.send(:element_path)
143
151
  end
144
-
152
+
145
153
  should "hit the Avvo API with the correct URL when retrieved" do
146
- stub_request(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3/phones/4.json").to_return(:body => {:id => '4'}.to_json)
154
+ stub_request(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3/phones/4.json")\
155
+ .to_return(:body => {:phone => {:id => '4'}}.to_json)
147
156
  ReactiveResource::Phone.find(4, :params => {:doctor_id => 2, :address_id => 3})
148
157
  assert_requested(:get, "https://api.avvo.com/api/1/doctors/2/addresses/3/phones/4.json")
149
158
  end
@@ -153,15 +162,17 @@ class ReactiveResource::BaseTest < Test::Unit::TestCase
153
162
 
154
163
  context "A resource without an extension" do
155
164
  should "hit the correct urls" do
156
- stub_request(:get, "https://api.avvo.com/api/1/no_extensions")
165
+ stub_request(:get, "https://api.avvo.com/api/1/no_extensions")\
166
+ .to_return(:body => [].to_json)
157
167
  @object = ReactiveResource::NoExtension.find(:all)
158
168
  assert_requested(:get, "https://api.avvo.com/api/1/no_extensions")
159
169
 
160
- stub_request(:put, "https://api.avvo.com/api/1/no_extensions/1")
170
+ stub_request(:post, "https://api.avvo.com/api/1/no_extensions")
161
171
  @object = ReactiveResource::NoExtension.new(:id => 1).save
162
- assert_requested(:put, "https://api.avvo.com/api/1/no_extensions/1")
172
+ assert_requested(:post, "https://api.avvo.com/api/1/no_extensions")
163
173
 
164
- stub_request(:get, "https://api.avvo.com/api/1/no_extensions/test")
174
+ stub_request(:get, "https://api.avvo.com/api/1/no_extensions/test")\
175
+ .to_return(:body => {:test => {:id => 1}}.to_json)
165
176
  @object = ReactiveResource::NoExtension.get(:test)
166
177
  assert_requested(:get, "https://api.avvo.com/api/1/no_extensions/test")
167
178
  end
metadata CHANGED
@@ -1,78 +1,69 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: reactive_resource
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 6
8
- - 1
9
- version: 0.6.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Justin Weiss
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-04-14 00:00:00 -07:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-03-06 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: activeresource
16
+ requirement: &70203673686620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
22
+ type: :runtime
22
23
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: *70203673686620
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70203673686140 !ruby/object:Gem::Requirement
24
28
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 2
30
- - 3
31
- - 10
32
- version: 2.3.10
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '3.1'
33
33
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: shoulda
37
34
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
35
+ version_requirements: *70203673686140
36
+ - !ruby/object:Gem::Dependency
37
+ name: shoulda
38
+ requirement: &70203673685680 !ruby/object:Gem::Requirement
39
39
  none: false
40
- requirements:
40
+ requirements:
41
41
  - - ~>
42
- - !ruby/object:Gem::Version
43
- segments:
44
- - 2
45
- - 11
46
- - 3
42
+ - !ruby/object:Gem::Version
47
43
  version: 2.11.3
48
44
  type: :development
49
- version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: webmock
52
45
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
46
+ version_requirements: *70203673685680
47
+ - !ruby/object:Gem::Dependency
48
+ name: webmock
49
+ requirement: &70203673685220 !ruby/object:Gem::Requirement
54
50
  none: false
55
- requirements:
51
+ requirements:
56
52
  - - ~>
57
- - !ruby/object:Gem::Version
58
- segments:
59
- - 1
60
- - 6
61
- - 1
53
+ - !ruby/object:Gem::Version
62
54
  version: 1.6.1
63
55
  type: :development
64
- version_requirements: *id003
56
+ prerelease: false
57
+ version_requirements: *70203673685220
65
58
  description: ActiveRecord-like associations for ActiveResource
66
- email:
59
+ email:
67
60
  - justin@uberweiss.org
68
61
  executables: []
69
-
70
62
  extensions: []
71
-
72
63
  extra_rdoc_files: []
73
-
74
- files:
64
+ files:
75
65
  - .gitignore
66
+ - .travis.yml
76
67
  - Gemfile
77
68
  - Gemfile.lock
78
69
  - LICENSE
@@ -91,39 +82,37 @@ files:
91
82
  - test/test_helper.rb
92
83
  - test/test_objects.rb
93
84
  - test/unit/base_test.rb
94
- has_rdoc: true
95
- homepage: ""
85
+ homepage: ''
96
86
  licenses: []
97
-
98
87
  post_install_message:
99
88
  rdoc_options: []
100
-
101
- require_paths:
89
+ require_paths:
102
90
  - lib
103
- required_ruby_version: !ruby/object:Gem::Requirement
91
+ required_ruby_version: !ruby/object:Gem::Requirement
104
92
  none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- segments:
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ segments:
109
98
  - 0
110
- version: "0"
111
- required_rubygems_version: !ruby/object:Gem::Requirement
99
+ hash: -1783378317626943238
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
101
  none: false
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- segments:
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ segments:
117
107
  - 0
118
- version: "0"
108
+ hash: -1783378317626943238
119
109
  requirements: []
120
-
121
110
  rubyforge_project: reactive_resource
122
- rubygems_version: 1.3.7
111
+ rubygems_version: 1.8.10
123
112
  signing_key:
124
113
  specification_version: 3
125
114
  summary: ActiveRecord-like associations for ActiveResource
126
- test_files:
115
+ test_files:
127
116
  - test/test_helper.rb
128
117
  - test/test_objects.rb
129
118
  - test/unit/base_test.rb