api_resource 0.5.1 → 0.6.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/.document +5 -0
- data/.gitignore +55 -0
- data/.rspec +8 -0
- data/.travis.yml +9 -0
- data/Gemfile +3 -36
- data/Gemfile.lock +37 -57
- data/Guardfile +7 -1
- data/{LICENSE.txt → LICENSE} +4 -2
- data/README.md +29 -0
- data/README.rdoc +5 -1
- data/Rakefile +5 -36
- data/api_resource.gemspec +40 -104
- data/lib/api_resource.rb +4 -1
- data/lib/api_resource/associations.rb +30 -14
- data/lib/api_resource/associations/association_proxy.rb +97 -0
- data/lib/api_resource/associations/belongs_to_remote_object_proxy.rb +0 -1
- data/lib/api_resource/associations/has_many_remote_object_proxy.rb +0 -1
- data/lib/api_resource/associations/has_one_remote_object_proxy.rb +7 -4
- data/lib/api_resource/associations/multi_object_proxy.rb +11 -16
- data/lib/api_resource/associations/single_object_proxy.rb +8 -6
- data/lib/api_resource/attributes.rb +29 -41
- data/lib/api_resource/base.rb +31 -102
- data/lib/api_resource/conditions.rb +36 -0
- data/lib/api_resource/conditions/abstract_condition.rb +112 -0
- data/lib/api_resource/conditions/association_condition.rb +18 -0
- data/lib/api_resource/conditions/include_condition.rb +16 -0
- data/lib/api_resource/conditions/multi_object_association_condition.rb +17 -0
- data/lib/api_resource/conditions/scope_condition.rb +11 -0
- data/lib/api_resource/conditions/single_object_association_condition.rb +19 -0
- data/lib/api_resource/connection.rb +18 -12
- data/lib/api_resource/finders.rb +122 -0
- data/lib/api_resource/finders/abstract_finder.rb +89 -0
- data/lib/api_resource/finders/multi_object_association_finder.rb +39 -0
- data/lib/api_resource/finders/resource_finder.rb +33 -0
- data/lib/api_resource/finders/single_object_association_finder.rb +40 -0
- data/lib/api_resource/observing.rb +19 -3
- data/lib/api_resource/scopes.rb +3 -3
- data/lib/api_resource/typecast.rb +85 -0
- data/lib/api_resource/typecasters/array_typecaster.rb +19 -0
- data/lib/api_resource/typecasters/boolean_typecaster.rb +22 -0
- data/lib/api_resource/typecasters/date_typecaster.rb +35 -0
- data/lib/api_resource/typecasters/float_typecaster.rb +22 -0
- data/lib/api_resource/typecasters/integer_typecaster.rb +22 -0
- data/lib/api_resource/typecasters/string_typecaster.rb +19 -0
- data/lib/api_resource/typecasters/time_typecaster.rb +44 -0
- data/lib/api_resource/version.rb +3 -0
- data/spec/lib/api_resource_spec.rb +6 -0
- data/spec/lib/associations/association_scope_spec.rb +1 -1
- data/spec/lib/associations_spec.rb +17 -50
- data/spec/lib/base_spec.rb +22 -0
- data/spec/lib/conditions/abstract_conditions_spec.rb +78 -0
- data/spec/lib/connection_spec.rb +19 -0
- data/spec/lib/finders/multi_object_association_finder_spec.rb +43 -0
- data/spec/lib/finders/resource_finder_spec.rb +89 -0
- data/spec/lib/finders/single_object_association_finder_spec.rb +43 -0
- data/spec/lib/observing_spec.rb +96 -0
- data/spec/lib/typecast_spec.rb +174 -0
- data/spec/lib/typecasters/boolean_typecaster_spec.rb +33 -0
- data/spec/lib/typecasters/date_typecaster_spec.rb +62 -0
- data/spec/lib/typecasters/float_typecaster_spec.rb +39 -0
- data/spec/lib/typecasters/integer_typecaster_spec.rb +40 -0
- data/spec/lib/typecasters/string_typecaster_spec.rb +28 -0
- data/spec/lib/typecasters/time_typecaster_spec.rb +65 -0
- data/spec/spec_helper.rb +0 -1
- metadata +134 -194
- data/VERSION +0 -1
- data/coverage/assets/0.5.3/app.js +0 -88
- data/coverage/assets/0.5.3/fancybox/blank.gif +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_close.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_loading.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_nav_left.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_nav_right.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_e.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_n.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_ne.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_nw.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_s.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_se.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_sw.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_shadow_w.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_title_left.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_title_main.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_title_over.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancy_title_right.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancybox-x.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancybox-y.png +0 -0
- data/coverage/assets/0.5.3/fancybox/fancybox.png +0 -0
- data/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/coverage/assets/0.5.3/favicon_green.png +0 -0
- data/coverage/assets/0.5.3/favicon_red.png +0 -0
- data/coverage/assets/0.5.3/favicon_yellow.png +0 -0
- data/coverage/assets/0.5.3/highlight.css +0 -129
- data/coverage/assets/0.5.3/highlight.pack.js +0 -1
- data/coverage/assets/0.5.3/jquery-1.6.2.min.js +0 -18
- data/coverage/assets/0.5.3/jquery.dataTables.min.js +0 -152
- data/coverage/assets/0.5.3/jquery.timeago.js +0 -141
- data/coverage/assets/0.5.3/jquery.url.js +0 -174
- data/coverage/assets/0.5.3/loading.gif +0 -0
- data/coverage/assets/0.5.3/magnify.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.5.3/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/assets/0.5.3/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/coverage/assets/0.5.3/stylesheet.css +0 -383
- data/coverage/assets/0.7.1/application.css +0 -1110
- data/coverage/assets/0.7.1/application.js +0 -626
- data/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/coverage/assets/0.7.1/loading.gif +0 -0
- data/coverage/assets/0.7.1/magnify.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/index.html +0 -3564
- data/lib/api_resource/associations/abstract_scope.rb +0 -191
- data/lib/api_resource/associations/association_scope.rb +0 -47
- data/lib/api_resource/associations/resource_scope.rb +0 -21
- data/lib/api_resource/associations/scope.rb +0 -34
- data/spec/lib/associations/resource_scope_spec.rb +0 -24
- data/spec/tmp/api_resource_test_db.sqlite +0 -0
- data/tmp/rspec_guard_result +0 -1
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
module ApiResource
|
|
2
|
-
|
|
3
|
-
module Associations
|
|
4
|
-
|
|
5
|
-
class AbstractScope
|
|
6
|
-
|
|
7
|
-
attr_reader :klass, :finder_opts
|
|
8
|
-
|
|
9
|
-
def initialize(klass, finder_opts = {})
|
|
10
|
-
|
|
11
|
-
# the base class for our scope, e.g. ApiResource::SomeClass
|
|
12
|
-
@klass = klass.is_a?(String) ? klass.constantize : klass
|
|
13
|
-
|
|
14
|
-
# load the resource definition
|
|
15
|
-
@klass.load_resource_definition
|
|
16
|
-
|
|
17
|
-
# the parent scope - for composing all of the finder options
|
|
18
|
-
@parent = finder_opts.delete(:__parent)
|
|
19
|
-
|
|
20
|
-
@finder_opts = finder_opts
|
|
21
|
-
|
|
22
|
-
# Where subscope is any scope down the chain, e.g. active.*future*
|
|
23
|
-
@klass.scopes.each do |scope_name, scope_definition|
|
|
24
|
-
self.define_subscope(scope_name, scope_definition)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def ttl
|
|
29
|
-
@ttl || 0
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# Use this method to access the internal data, this guarantees that loading only occurs once per object
|
|
33
|
-
def internal_object
|
|
34
|
-
if instance_variable_defined?(:@internal_object)
|
|
35
|
-
return instance_variable_get(:@internal_object)
|
|
36
|
-
end
|
|
37
|
-
instance_variable_set(:@internal_object, self.load)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# has the scope been loaded?
|
|
41
|
-
def loaded?
|
|
42
|
-
@loaded == true
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def load_resource_definition
|
|
46
|
-
self.klass.load_resource_definition
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def scopes
|
|
50
|
-
@scopes ||= HashWithIndifferentAccess.new
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def scope?(scp)
|
|
54
|
-
self.scopes.key?(scp.to_s)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# def current_scope
|
|
58
|
-
# ActiveSupport::StringInquirer.new(@current_scope.join("_and_").concat("_scope"))
|
|
59
|
-
# end
|
|
60
|
-
|
|
61
|
-
def to_hash
|
|
62
|
-
self.parent_hash.merge(self.finder_opts)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# takes empty hashes and replaces them with true so that to_query doesn't strip them out
|
|
66
|
-
def to_query_safe_hash(hash)
|
|
67
|
-
hash.each_pair do |k, v|
|
|
68
|
-
hash[k] = to_query_safe_hash(v) if v.is_a?(Hash)
|
|
69
|
-
hash[k] = true if v == {}
|
|
70
|
-
end
|
|
71
|
-
return hash
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# gets the current hash and calls to_query on it
|
|
75
|
-
def to_query
|
|
76
|
-
#We need to add the unescape because to_query breaks on nested arrays
|
|
77
|
-
CGI.unescape(to_query_safe_hash(self.to_hash).to_query)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# unset all of our scope values and our internal object
|
|
81
|
-
def reload
|
|
82
|
-
(self.scopes.keys + [:internal_object]).each do |ivar|
|
|
83
|
-
if instance_variable_defined?("@#{ivar}")
|
|
84
|
-
remove_instance_variable("@#{ivar}")
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
@loaded = false
|
|
88
|
-
self
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def to_s
|
|
92
|
-
self.internal_object.to_s
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def inspect
|
|
96
|
-
self.internal_object.inspect
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def blank?
|
|
100
|
-
self.internal_object.blank?
|
|
101
|
-
end
|
|
102
|
-
alias_method :empty?, :blank?
|
|
103
|
-
|
|
104
|
-
def present?
|
|
105
|
-
self.internal_object.present?
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def expires_in(ttl)
|
|
109
|
-
ApiResource::Decorators::CachingDecorator.new(self, ttl)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
protected
|
|
113
|
-
|
|
114
|
-
# scope_name => e.g. paged
|
|
115
|
-
# scope_definition => e.g. {:page => "req", "per_page" => "opt"}
|
|
116
|
-
|
|
117
|
-
def define_subscope(scope_name, scope_definition)
|
|
118
|
-
|
|
119
|
-
self.scopes[scope_name] = scope_definition
|
|
120
|
-
|
|
121
|
-
self.class_eval do
|
|
122
|
-
|
|
123
|
-
define_method(scope_name) do |*args|
|
|
124
|
-
|
|
125
|
-
unless instance_variable_defined?("@#{scope_name}")
|
|
126
|
-
|
|
127
|
-
arg_names = scope_definition.keys
|
|
128
|
-
arg_types = scope_definition.values
|
|
129
|
-
|
|
130
|
-
finder_opts = {
|
|
131
|
-
scope_name => {}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
arg_names.each_with_index do |arg_name, i|
|
|
135
|
-
|
|
136
|
-
# If we are dealing with a scope with multiple args
|
|
137
|
-
if arg_types[i] == :rest
|
|
138
|
-
finder_opts[scope_name][arg_name] =
|
|
139
|
-
args.slice(i, args.count)
|
|
140
|
-
# Else we are only dealing with a single argument
|
|
141
|
-
else
|
|
142
|
-
if arg_types[i] == :req || args[i].present?
|
|
143
|
-
finder_opts[scope_name][arg_name] = args[i]
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
# if we have nothing at this point we should just pass 'true'
|
|
149
|
-
if finder_opts[scope_name] == {}
|
|
150
|
-
finder_opts[scope_name] = true
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
instance_variable_set(
|
|
154
|
-
"@#{scope_name}",
|
|
155
|
-
self.get_subscope_instance(finder_opts)
|
|
156
|
-
)
|
|
157
|
-
end
|
|
158
|
-
instance_variable_get("@#{scope_name}")
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def get_subscope_instance(finder_opts)
|
|
164
|
-
ApiResource::Associations::Scope.new(
|
|
165
|
-
self, finder_opts.merge(:__parent => self)
|
|
166
|
-
)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def method_missing(method, *args, &block)
|
|
170
|
-
self.internal_object.send(method, *args, &block)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# querystring hash from parent
|
|
174
|
-
def parent_hash
|
|
175
|
-
@parent ? @parent.to_hash : {}
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# require our subclasses to implement a way to find records
|
|
179
|
-
def load
|
|
180
|
-
raise NotImplementedError.new("#{self.class} must implement #load")
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
# make sure we have a valid scope
|
|
184
|
-
def check_scope(scp)
|
|
185
|
-
raise ArgumentError, "Unknown scope #{scp}" unless self.scope?(scp.to_s)
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
module ApiResource
|
|
2
|
-
|
|
3
|
-
module Associations
|
|
4
|
-
|
|
5
|
-
class AssociationScope < AbstractScope
|
|
6
|
-
|
|
7
|
-
class_attribute :remote_path_element
|
|
8
|
-
self.remote_path_element = :service_uri
|
|
9
|
-
|
|
10
|
-
attr_accessor :remote_path
|
|
11
|
-
attr_reader :owner
|
|
12
|
-
|
|
13
|
-
# TODO: added owner - moved it to the end because the tests don't use it - it's useful here though
|
|
14
|
-
def initialize(klass, owner, opts = {})
|
|
15
|
-
super(klass)
|
|
16
|
-
|
|
17
|
-
@owner = owner
|
|
18
|
-
|
|
19
|
-
self.internal_object = opts
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def ==(other)
|
|
23
|
-
raise "Not Implemented: This method must be implemented in a subclass"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def scopes
|
|
27
|
-
self.klass.scopes
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
protected
|
|
31
|
-
|
|
32
|
-
# get the remote URI based on our config and options
|
|
33
|
-
def build_load_path(options)
|
|
34
|
-
path = self.remote_path
|
|
35
|
-
# add a format if it doesn't exist and there is no query string yet
|
|
36
|
-
path += ".#{self.klass.format.extension}" unless path =~ /\./ || path =~/\?/
|
|
37
|
-
# add the query string, allowing for other user-provided options in the remote_path if we have options
|
|
38
|
-
unless options.blank?
|
|
39
|
-
path += (path =~ /\?/ ? "&" : "?") + options.to_query
|
|
40
|
-
end
|
|
41
|
-
path
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module ApiResource
|
|
2
|
-
module Associations
|
|
3
|
-
class ResourceScope < AbstractScope
|
|
4
|
-
|
|
5
|
-
include Enumerable
|
|
6
|
-
|
|
7
|
-
alias_method :all, :internal_object
|
|
8
|
-
|
|
9
|
-
def each(*args, &block)
|
|
10
|
-
self.internal_object.each(*args, &block)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# perform a find with a given set of query params
|
|
14
|
-
def load(opts = self.to_hash)
|
|
15
|
-
ret = self.klass.all(:params => opts)
|
|
16
|
-
@loaded = true
|
|
17
|
-
ret
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
module ApiResource
|
|
2
|
-
module Associations
|
|
3
|
-
class Scope < AbstractScope
|
|
4
|
-
|
|
5
|
-
def initialize(klass, opts = {})
|
|
6
|
-
# see if we have a hash of options and it has a parent in it
|
|
7
|
-
unless opts[:__parent].respond_to?(:load)
|
|
8
|
-
raise ArgumentError.new(
|
|
9
|
-
"Scopes must have a parent object passed in that " +
|
|
10
|
-
"responds to #load"
|
|
11
|
-
)
|
|
12
|
-
end
|
|
13
|
-
super(klass, opts)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def load
|
|
17
|
-
ret = self.klass.load(self.to_hash)
|
|
18
|
-
@loaded = true
|
|
19
|
-
ret
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# we break this out here because Scope needs to pass self.klass to
|
|
23
|
-
# any sub-scopes. This is because Scope does not have knowledge
|
|
24
|
-
# of how to actually load data and delegates that to either
|
|
25
|
-
# a ResourceScope or an AssociationScope
|
|
26
|
-
def get_subscope_instance(finder_opts)
|
|
27
|
-
ApiResource::Associations::Scope.new(
|
|
28
|
-
self.klass, finder_opts.merge(:__parent => self)
|
|
29
|
-
)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe ApiResource::Associations::ResourceScope do
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
context "#load" do
|
|
7
|
-
|
|
8
|
-
it "should perform the correct query" do
|
|
9
|
-
|
|
10
|
-
TestResource.expects(:all)
|
|
11
|
-
.with(:params => {
|
|
12
|
-
"birthday" => {
|
|
13
|
-
"date" => "2012-01-01"
|
|
14
|
-
}
|
|
15
|
-
})
|
|
16
|
-
.returns([])
|
|
17
|
-
|
|
18
|
-
TestResource.birthday("2012-01-01").first
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end
|
|
Binary file
|
data/tmp/rspec_guard_result
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|