api_resource 0.6.1 → 0.6.2
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/Gemfile.lock +4 -4
- data/lib/api_resource/associations.rb +24 -12
- data/lib/api_resource/base.rb +10 -0
- data/lib/api_resource/finders/abstract_finder.rb +8 -3
- data/lib/api_resource/scopes.rb +1 -1
- data/lib/api_resource/version.rb +1 -1
- data/spec/lib/associations_spec.rb +36 -0
- data/spec/lib/conditions/abstract_conditions_spec.rb +7 -0
- data/spec/lib/finders_spec.rb +19 -0
- metadata +2 -2
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
api_resource (0.6.
|
4
|
+
api_resource (0.6.1)
|
5
5
|
colorize
|
6
6
|
differ
|
7
7
|
json
|
@@ -69,7 +69,7 @@ GEM
|
|
69
69
|
guard-rspec (2.3.3)
|
70
70
|
guard (>= 1.1)
|
71
71
|
rspec (~> 2.11)
|
72
|
-
guard-spork (1.4.
|
72
|
+
guard-spork (1.4.1)
|
73
73
|
childprocess (>= 0.2.3)
|
74
74
|
guard (>= 1.1)
|
75
75
|
spork (>= 0.8.4)
|
@@ -81,7 +81,7 @@ GEM
|
|
81
81
|
i18n (0.6.1)
|
82
82
|
journey (1.0.4)
|
83
83
|
json (1.7.6)
|
84
|
-
listen (0.7.
|
84
|
+
listen (0.7.1)
|
85
85
|
log4r (1.1.10)
|
86
86
|
lumberjack (1.0.2)
|
87
87
|
mail (2.4.4)
|
@@ -99,7 +99,7 @@ GEM
|
|
99
99
|
coderay (~> 1.0.5)
|
100
100
|
method_source (~> 0.8)
|
101
101
|
slop (~> 3.3.1)
|
102
|
-
rack (1.4.
|
102
|
+
rack (1.4.3)
|
103
103
|
rack-cache (1.2)
|
104
104
|
rack (>= 0.4)
|
105
105
|
rack-ssl (1.3.2)
|
@@ -8,6 +8,7 @@ module ApiResource
|
|
8
8
|
#TODO: many of these methods should also force loading of the resource definition
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
extend ActiveSupport::Autoload
|
11
|
+
include ActiveModel::Dirty
|
11
12
|
|
12
13
|
autoload :AssociationProxy
|
13
14
|
autoload :BelongsToRemoteObjectProxy
|
@@ -142,11 +143,18 @@ module ApiResource
|
|
142
143
|
end
|
143
144
|
|
144
145
|
# TODO: add a special foreign_key option to associations
|
145
|
-
def association_foreign_key_field(assoc)
|
146
|
+
def association_foreign_key_field(assoc, type = nil)
|
147
|
+
|
148
|
+
if type.nil? && has_many?(assoc)
|
149
|
+
type = :has_many
|
150
|
+
else
|
151
|
+
type = type.to_s.to_sym
|
152
|
+
end
|
153
|
+
|
146
154
|
# for now just use the association name
|
147
155
|
str = assoc.to_s.singularize.foreign_key
|
148
156
|
|
149
|
-
if has_many
|
157
|
+
if type == :has_many
|
150
158
|
str = str.pluralize
|
151
159
|
end
|
152
160
|
|
@@ -177,19 +185,15 @@ module ApiResource
|
|
177
185
|
end
|
178
186
|
|
179
187
|
def define_association_as_attribute(assoc_type, assoc_name)
|
188
|
+
id_method_name = association_foreign_key_field(assoc_name, assoc_type)
|
189
|
+
|
180
190
|
# set up dirty tracking for associations, but only for ApiResource
|
181
191
|
# these methods are also used for ActiveRecord
|
182
192
|
# TODO: change this
|
183
193
|
if self.ancestors.include?(ApiResource::Base)
|
184
194
|
define_attribute_method(assoc_name)
|
195
|
+
define_attribute_method(id_method_name)
|
185
196
|
end
|
186
|
-
|
187
|
-
id_method_name = assoc_name.to_s.singularize + "_id"
|
188
|
-
|
189
|
-
if assoc_type.to_s == "has_many"
|
190
|
-
id_method_name += "s"
|
191
|
-
end
|
192
|
-
|
193
197
|
# TODO: Come up with a better implementation for the foreign key thing
|
194
198
|
# implement the rest of the active record methods, refactor this into something
|
195
199
|
# a little bit more sensible
|
@@ -223,11 +227,19 @@ module ApiResource
|
|
223
227
|
end
|
224
228
|
|
225
229
|
def #{id_method_name}
|
226
|
-
@attributes_cache[:#{id_method_name}] ||=
|
227
|
-
|
230
|
+
@attributes_cache[:#{id_method_name}] ||= begin
|
231
|
+
if @attributes.key?(:#{id_method_name})
|
232
|
+
@attributes[:#{id_method_name}]
|
233
|
+
else
|
234
|
+
self.#{assoc_name}.collect(&:id)
|
235
|
+
end
|
236
|
+
end
|
228
237
|
end
|
229
238
|
|
230
|
-
def #{id_method_name}=(val)
|
239
|
+
def #{id_method_name}=(val, force = false)
|
240
|
+
unless @attributes_cache[:#{id_method_name}] == val
|
241
|
+
#{id_method_name}_will_change!
|
242
|
+
end
|
231
243
|
@attributes_cache[:#{id_method_name}] = val
|
232
244
|
end
|
233
245
|
|
data/lib/api_resource/base.rb
CHANGED
@@ -536,6 +536,16 @@ module ApiResource
|
|
536
536
|
!self.attribute?(key) || self.protected_attribute?(key) ? accum : accum.merge(key => val)
|
537
537
|
end
|
538
538
|
end
|
539
|
+
|
540
|
+
# also add in the _id fields that are changed
|
541
|
+
ret = self.association_names.inject(ret) do |accum, assoc_name|
|
542
|
+
id_method = self.class.association_foreign_key_field(assoc_name)
|
543
|
+
if self.changes[id_method].present?
|
544
|
+
accum[id_method] = self.changes[id_method].last
|
545
|
+
end
|
546
|
+
accum
|
547
|
+
end
|
548
|
+
|
539
549
|
options[:include_associations].each do |assoc|
|
540
550
|
if self.association?(assoc)
|
541
551
|
ret[assoc] = self.send(assoc).serializable_hash({
|
@@ -60,9 +60,14 @@ module ApiResource
|
|
60
60
|
id_hash = HashWithIndifferentAccess.new(id_hash)
|
61
61
|
# load each individually
|
62
62
|
self.condition.included_objects.inject(hsh) do |accum, assoc|
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
id_hash[assoc].each_slice(400).each do |ids|
|
64
|
+
accum[assoc.to_sym] ||= []
|
65
|
+
accum[assoc.to_sym].concat(
|
66
|
+
self.klass.association_class(assoc).all(
|
67
|
+
:params => {:ids => ids}
|
68
|
+
)
|
69
|
+
)
|
70
|
+
end
|
66
71
|
accum
|
67
72
|
end
|
68
73
|
|
data/lib/api_resource/scopes.rb
CHANGED
@@ -51,7 +51,7 @@ module ApiResource
|
|
51
51
|
args.slice(i, args.count)
|
52
52
|
# Else we are only dealing with a single argument
|
53
53
|
else
|
54
|
-
if arg_types[i] == :req || args
|
54
|
+
if arg_types[i] == :req || (i < args.count)
|
55
55
|
finder_opts[scope_name][arg_name] = args[i]
|
56
56
|
end
|
57
57
|
end
|
data/lib/api_resource/version.rb
CHANGED
@@ -260,6 +260,21 @@ describe "Associations" do
|
|
260
260
|
ap.test.should eql("testval")
|
261
261
|
|
262
262
|
end
|
263
|
+
|
264
|
+
it "should include the foreign_key_id when saving" do
|
265
|
+
tr = TestResource.new
|
266
|
+
tr.belongs_to_object_id = 4
|
267
|
+
hsh = tr.serializable_hash
|
268
|
+
hsh[:belongs_to_object_id].should eql(4)
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should serialize the foreign_key_id when saving if it is updated" do
|
272
|
+
TestResource.connection
|
273
|
+
tr = TestResource.find(1)
|
274
|
+
tr.belongs_to_object_id = 5
|
275
|
+
hsh = tr.serializable_hash
|
276
|
+
hsh[:belongs_to_object_id].should eql(5)
|
277
|
+
end
|
263
278
|
end
|
264
279
|
|
265
280
|
describe "Multi Object Associations" do
|
@@ -343,6 +358,27 @@ describe "Associations" do
|
|
343
358
|
)
|
344
359
|
ap.remote_path.should eql("/route")
|
345
360
|
end
|
361
|
+
|
362
|
+
it "should include the foreign_key_id when saving" do
|
363
|
+
tr = TestResource.new
|
364
|
+
tr.has_many_object_ids = [4]
|
365
|
+
hsh = tr.serializable_hash
|
366
|
+
hsh[:has_many_object_ids].should eql([4])
|
367
|
+
end
|
368
|
+
|
369
|
+
it "should serialize the foreign_key_id when saving if it is updated" do
|
370
|
+
tr = TestResource.find(1)
|
371
|
+
tr.has_many_object_ids = [5]
|
372
|
+
hsh = tr.serializable_hash
|
373
|
+
hsh[:has_many_object_ids].should eql([5])
|
374
|
+
end
|
375
|
+
|
376
|
+
it "should not try to load if the foreign key is nil" do
|
377
|
+
TestResource.connection.expects(:get).returns(:id => 1, :belongs_to_object_id => nil)
|
378
|
+
tr = TestResource.find(1)
|
379
|
+
tr.id.should eql(1)
|
380
|
+
tr.belongs_to_object_id.should be_nil
|
381
|
+
end
|
346
382
|
end
|
347
383
|
|
348
384
|
end
|
@@ -75,4 +75,11 @@ describe "Conditions" do
|
|
75
75
|
obj.collect{|o| o * 2}.should eql([2,4])
|
76
76
|
end
|
77
77
|
|
78
|
+
it "should not typecast nil and false to true when creating condition hashes" do
|
79
|
+
obj = TestResource.paginate(false, nil)
|
80
|
+
hsh = obj.to_hash["paginate"]
|
81
|
+
hsh["per_page"].should eql(false)
|
82
|
+
hsh.should be_key(:current_page)
|
83
|
+
end
|
84
|
+
|
78
85
|
end
|
data/spec/lib/finders_spec.rb
CHANGED
@@ -35,4 +35,23 @@ describe ApiResource::Finders do
|
|
35
35
|
TestResource.includes(:has_many_objects).find(1)
|
36
36
|
end
|
37
37
|
|
38
|
+
it "should be able to use a scope with arguments" do
|
39
|
+
TestResource.connection.expects(:get)
|
40
|
+
.with("/test_resources.json?active=true&birthday%5Bdate%5D=5").returns([{"id" => 10}])
|
41
|
+
|
42
|
+
res = TestResource.active.birthday(5).all
|
43
|
+
res.should be_a(Array)
|
44
|
+
res.first.id.should eql(10)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be able to use a scope with multiple arguments" do
|
48
|
+
TestResource.connection.expects(:get)
|
49
|
+
.with("/test_resources.json?paginate%5Bcurrent_page%5D=10&paginate%5Bper_page%5D=5")
|
50
|
+
.returns([{:id => 20}])
|
51
|
+
|
52
|
+
res = TestResource.paginate(5, 10).all
|
53
|
+
res.should be_a(Array)
|
54
|
+
res.first.id.should eql(20)
|
55
|
+
end
|
56
|
+
|
38
57
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-01-
|
14
|
+
date: 2013-01-07 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rake
|