arrest 0.0.67 → 0.0.68

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,8 +9,6 @@ require "arrest/attributes/attribute"
9
9
  require "arrest/attributes/nested_attribute"
10
10
  require "arrest/attributes/nested_collection"
11
11
  require "arrest/attributes/belongs_to_attribute"
12
- require "arrest/attributes/has_many_attribute"
13
- require "arrest/attributes/has_many_sub_resource_attribute"
14
12
  require "arrest/attributes/polymorphic_attribute"
15
13
  require "arrest/attributes/converter"
16
14
  require "arrest/class_utils.rb"
@@ -21,6 +19,7 @@ require "arrest/helper/filter"
21
19
  require "arrest/helper/child_collection"
22
20
  require "arrest/helper/ordered_collection"
23
21
  require "arrest/helper/has_many_collection"
22
+ require "arrest/helper/ids_collection"
24
23
  require "arrest/helper/has_many"
25
24
  require "arrest/helper/has_view"
26
25
  require "arrest/exceptions"
@@ -70,7 +70,6 @@ module Arrest
70
70
  extend ActiveModel::Naming
71
71
  include ActiveModel::Validations
72
72
  include ActiveModel::Conversion
73
- include ActiveModel::Dirty
74
73
  include ActiveModel::Validations::Callbacks
75
74
  extend ActiveModel::Callbacks
76
75
  extend ActiveModel::Translation
@@ -113,14 +112,6 @@ module Arrest
113
112
 
114
113
  def build(context, hash)
115
114
  resource = self.new(context, hash, true)
116
-
117
- # traverse fields for subresources and fill them in
118
- self.all_fields.find_all{|f| f.is_a?(HasManySubResourceAttribute)}.each do |attr|
119
- ids = AbstractResource::source.get_many_other_ids(context, "#{resource.resource_location}/#{attr.sub_resource_field_name}")
120
- resource.send("#{attr.name}=", body_root(ids))
121
- end
122
- resource.clear_dirtiness()
123
-
124
115
  resource
125
116
  end
126
117
 
@@ -226,30 +217,13 @@ module Arrest
226
217
  initialize_has_attributes(hash, from_json)
227
218
  end
228
219
 
229
- def clear_dirtiness
230
- @changed_attributes.clear if @changed_attributes
231
- end
232
-
233
220
  def save
234
221
  if Source.skip_validations || self.valid?
235
222
  req_type = new_record? ? :post : :put
236
- success = !!AbstractResource::source.send(req_type, @context, self)
237
-
238
- if success
239
- # check for sub resources in case of n:m relationships
240
- self.class.all_fields.find_all{|f| f.is_a?(HasManySubResourceAttribute)}.each do |attr|
241
- if !attr.sub_resource_read_only? && self.send("#{attr.name}_changed?") # check whether this 'subresource' attribute has been touched
242
- ids = self.send(attr.name) # get ids_field e.g. for team has_many :users get 'self.user_ids'
243
- srifn = attr.sub_resource_field_name
244
- result = !!AbstractResource::source.put_sub_resource(self, srifn, ids)
245
- return false if !result
246
- end
247
- end
248
- clear_dirtiness() # unset the dirtiness after saving (only used for HasManySubResourceAttributes), see ActiveModel::Dirty
249
- return true
250
- end
223
+ !!AbstractResource::source.send(req_type, @context, self)
224
+ else
225
+ false
251
226
  end
252
- false
253
227
  end
254
228
 
255
229
  def save!
@@ -259,6 +233,7 @@ module Arrest
259
233
  def reload
260
234
  @child_collections = {}
261
235
  @views = {}
236
+ @belongs_tos = {}
262
237
  hash = internal_reload
263
238
  self.attributes= hash
264
239
  end
@@ -45,20 +45,22 @@ module Arrest
45
45
 
46
46
  send :define_method, name do
47
47
  val = self.send(field_name)
48
- if val == nil || val == ""
48
+ if val.blank?
49
49
  return nil
50
50
  end
51
51
 
52
- begin
53
- if polymorphic
54
- clazz = self.class.json_type_to_class(val.type)
55
- clazz.find(self.context, val.id)
56
- else
57
- Arrest::Source.mod.const_get(class_name).find(self.context, val)
52
+ @belongs_tos ||= {}
53
+ @belongs_tos[name] ||=
54
+ begin
55
+ if polymorphic
56
+ clazz = self.class.json_type_to_class(val.type)
57
+ clazz.find(self.context, val.id)
58
+ else
59
+ Arrest::Source.mod.const_get(class_name).find(self.context, val)
60
+ end
61
+ rescue Errors::DocumentNotFoundError => e
62
+ raise Errors::DocumentNotFoundError, "Couldnt find a #{class_name} with id #{val}"
58
63
  end
59
- rescue Errors::DocumentNotFoundError => e
60
- raise Errors::DocumentNotFoundError, "Couldnt find a #{class_name} with id #{val}"
61
- end
62
64
 
63
65
  end
64
66
  end
@@ -136,24 +136,10 @@ module Arrest
136
136
  def add_attribute(attribute)
137
137
  @fields ||= []
138
138
  # define setter for attribute value
139
- if (attribute.is_a?(HasManySubResourceAttribute))
140
- send :define_method, "#{attribute.name}=" do |v|
141
- raise ArgumentError, 'Argument is not of Array type' unless v.is_a?(Array)
142
- Arrest::debug "setter #{self.class.name} #{attribute.name} = #{v}"
143
-
144
- # inform ActiveModel::Dirty about dirtiness of this attribute
145
- self.send("#{attribute.name}_will_change!") unless v == self.attribute_values[attribute.name]
146
-
147
- self.attribute_values[attribute.name] = v
148
- end
149
- else
150
- send :define_method, "#{attribute.name}=" do |v|
151
- converted_v = convert(attribute, v)
152
- Arrest::debug "setter #{self.class.name} #{attribute.name} = #{converted_v}"
153
- self.attribute_values[attribute.name] = converted_v
154
- #Arrest::debug "setter #{self.class.name} #{attribute.name} = #{v}"
155
- #self.attribute_values[attribute.name] = v
156
- end
139
+ send :define_method, "#{attribute.name}=" do |v|
140
+ converted_v = convert(attribute, v)
141
+ Arrest::debug "setter #{self.class.name} #{attribute.name} = #{converted_v}"
142
+ self.attribute_values[attribute.name] = converted_v
157
143
  end
158
144
 
159
145
  # define getter for attribute value
@@ -7,54 +7,37 @@ module Arrest
7
7
  end
8
8
 
9
9
  module ClassMethods
10
- def has_many(*args)
11
- method_name, options = args
12
- ids_field_name = (StringUtils.singular(method_name.to_s) + '_ids').to_sym
13
- method_name = method_name.to_sym
14
- clazz_name = StringUtils.singular(method_name.to_s)
15
- foreign_key = clazz_name + "_id"
16
- sub_resource = false
10
+ def has_many(*args) # has_many :my_teams, :class_name => :Team
11
+ method_name, options = args # my_teams
12
+ ids_method_name = (StringUtils.singular(method_name.to_s) + '_ids').to_sym # my_team_ids
13
+ method_name = method_name.to_sym # :my_teams
14
+
15
+ clazz_name = StringUtils.singular(method_name.to_s) # my_team
16
+
17
+ ids_method_url_part = "/" + ids_method_name.to_s # /my_team_ids
18
+ method_url_part = "/" + method_name.to_s # /my_teams
19
+
17
20
  read_only = false
18
- url_part = "/" + method_name.to_s
19
21
  if options
20
- clazz_name = options[:class_name].to_s unless options[:class_name] == nil
21
- foreign_key = "#{StringUtils.underscore(clazz_name)}_id"
22
- foreign_key = options[:foreign_key].to_s unless options[:foreign_key] == nil
23
- sub_resource = !!options[:sub_resource]
24
- read_only = options[:read_only]
25
- url_part = "/" + options[:url_part].to_s unless options[:url_part] == nil
22
+ clazz_name = options[:class_name].to_s unless options[:class_name] == nil # :Team
23
+ foreign_key = "#{StringUtils.underscore(clazz_name)}_id" # team_id
24
+ foreign_key = options[:foreign_key].to_s unless options[:foreign_key] == nil # team_id
25
+ ids_method_url_part += "/" + options[:url_part].to_s unless options[:url_part] == nil # /my_team_ids + /my-url-part
26
+ method_url_part += "/" + options[:url_part].to_s unless options[:url_part] == nil # /my_teams + /my-url-part
27
+ read_only = !!options[:read_only] unless options[:read_only] == nil
26
28
  end
27
29
 
28
- hm_attr = create_has_many_attribute(sub_resource, # e.g. 'team_ids' attribute for 'has_many :teams'
29
- ids_field_name,
30
- method_name,
31
- clazz_name,
32
- url_part,
33
- foreign_key,
34
- read_only)
35
- add_attribute(hm_attr)
36
- send :define_method, method_name do |filter = {}|# e.g. define 'teams' method for notation 'has_many :teams'
37
- HasManyCollection.new(self, self.context, clazz_name, self.resource_location + url_part.to_s, filter)
38
- end
39
- end
40
30
 
41
- def create_has_many_attribute(sub_resource, ids_field_name, method_name,
42
- clazz_name, url_part, foreign_key, read_only)
43
- if sub_resource
44
- define_attribute_methods [ids_field_name]
45
- return HasManySubResourceAttribute.new(ids_field_name,
46
- method_name,
47
- clazz_name,
48
- url_part,
49
- foreign_key,
50
- read_only)
31
+ if read_only
32
+ send(:define_method, ids_method_name) do |filter = {}|
33
+ IdsCollection.new(self, self.resource_location + ids_method_url_part)
34
+ end
51
35
  else
52
- return HasManyAttribute.new(ids_field_name,
53
- method_name,
54
- clazz_name,
55
- url_part,
56
- foreign_key,
57
- read_only)
36
+ self.attribute ids_method_name.to_sym, Array
37
+ end
38
+
39
+ send(:define_method, method_name) do |filter = {}|
40
+ HasManyCollection.new(self, self.context, clazz_name, self.resource_location + method_url_part, filter)
58
41
  end
59
42
  end
60
43
  end
@@ -0,0 +1,31 @@
1
+ module Arrest
2
+ class IdsCollection
3
+
4
+ def initialize(parent, ids_url)
5
+ @collection = nil
6
+ @parent = parent
7
+ @url = ids_url
8
+ end
9
+
10
+ def method_missing(*args, &block)
11
+ collection.send(*args, &block)
12
+ end
13
+
14
+ def inspect
15
+ collection.inspect
16
+ end
17
+
18
+ private
19
+
20
+ def collection
21
+ unless @collection
22
+
23
+ r = @parent.class.source().get_one(@parent.context, "#{@url}")
24
+ @collection = @parent.class.body_root(r)
25
+
26
+ end
27
+ @collection
28
+ end
29
+
30
+ end
31
+ end
@@ -19,7 +19,9 @@ module Arrest
19
19
  @sort_hash = {}
20
20
  @query_params = query_params
21
21
 
22
+ # FIXME (bk, at) : propagate scopes to instances as well
22
23
  define_filters
24
+ define_scopes
23
25
  end
24
26
 
25
27
  def build(attributes = {})
@@ -157,6 +159,18 @@ module Arrest
157
159
  end
158
160
  end
159
161
 
162
+ def define_scopes
163
+ return unless resolved_class.scopes
164
+ resolved_class.scopes.each do |scope|
165
+ resource_name = scope.options[:resource_name] || scope.name
166
+ self.instance_eval <<-"end_eval"
167
+ def #{scope.name} query_params = {}
168
+ OrderedCollection.new(@context, ClassUtils.simple_name(resolved_class), "#{@base_url}/#{resource_name}", query_params)
169
+ end
170
+ end_eval
171
+ end
172
+ end
173
+
160
174
  end
161
175
  end
162
176
 
@@ -46,6 +46,7 @@ module Arrest
46
46
  get_one(context, path)
47
47
  end
48
48
 
49
+ # FIXME (bk, at) : seems to be identical to get_one - prepare to refactor
49
50
  def get_many(context, sub, filter={})
50
51
  headers = nil
51
52
  response = self.connection().get do |req|
@@ -57,6 +58,8 @@ module Arrest
57
58
  Arrest::Source.call_logger.log(rql, rsl)
58
59
  if response.env[:status] == 401
59
60
  raise Errors::PermissionDeniedError.new(response.body)
61
+ elsif response.env[:status] != 200
62
+ raise Errors::DocumentNotFoundError
60
63
  end
61
64
  response.body
62
65
  end
@@ -267,7 +267,7 @@ module Arrest
267
267
  e.name.to_s == sub_url && ids.include?(e.id)
268
268
  end
269
269
 
270
- @@edge_matrix[object_id].delete_if do |e|
270
+ @@edge_matrix[object_id].delete_if do |e|
271
271
  e.name.to_s == sub_url && !ids.include?(e.id)
272
272
  end
273
273
 
@@ -1,3 +1,3 @@
1
1
  module Arrest
2
- VERSION = "0.0.67"
2
+ VERSION = "0.0.68"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arrest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.67
4
+ version: 0.0.68
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-15 00:00:00.000000000Z
12
+ date: 2012-06-20 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &24259220 !ruby/object:Gem::Requirement
16
+ requirement: &25743060 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *24259220
24
+ version_requirements: *25743060
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: faraday
27
- requirement: &24258720 !ruby/object:Gem::Requirement
27
+ requirement: &25742560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.7.5
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *24258720
35
+ version_requirements: *25742560
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activemodel
38
- requirement: &24258220 !ruby/object:Gem::Requirement
38
+ requirement: &25742060 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '3'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *24258220
46
+ version_requirements: *25742060
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &24257760 !ruby/object:Gem::Requirement
49
+ requirement: &25741600 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *24257760
57
+ version_requirements: *25741600
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &24257380 !ruby/object:Gem::Requirement
60
+ requirement: &25741220 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *24257380
68
+ version_requirements: *25741220
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rdoc
71
- requirement: &24256920 !ruby/object:Gem::Requirement
71
+ requirement: &25740760 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *24256920
79
+ version_requirements: *25740760
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &24285260 !ruby/object:Gem::Requirement
82
+ requirement: &25740260 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '2'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *24285260
90
+ version_requirements: *25740260
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rr
93
- requirement: &24284840 !ruby/object:Gem::Requirement
93
+ requirement: &25739840 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *24284840
101
+ version_requirements: *25739840
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: simplecov
104
- requirement: &24284380 !ruby/object:Gem::Requirement
104
+ requirement: &25739380 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *24284380
112
+ version_requirements: *25739380
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rack
115
- requirement: &24283960 !ruby/object:Gem::Requirement
115
+ requirement: &25738960 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,7 +120,7 @@ dependencies:
120
120
  version: '0'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *24283960
123
+ version_requirements: *25738960
124
124
  description: Consume a rest API in a AR like fashion
125
125
  email:
126
126
  - axel.tetzlaff@fortytools.com
@@ -141,8 +141,6 @@ files:
141
141
  - lib/arrest/attributes/belongs_to_attribute.rb
142
142
  - lib/arrest/attributes/converter.rb
143
143
  - lib/arrest/attributes/has_attributes.rb
144
- - lib/arrest/attributes/has_many_attribute.rb
145
- - lib/arrest/attributes/has_many_sub_resource_attribute.rb
146
144
  - lib/arrest/attributes/nested_attribute.rb
147
145
  - lib/arrest/attributes/nested_collection.rb
148
146
  - lib/arrest/attributes/polymorphic_attribute.rb
@@ -154,6 +152,7 @@ files:
154
152
  - lib/arrest/helper/has_many.rb
155
153
  - lib/arrest/helper/has_many_collection.rb
156
154
  - lib/arrest/helper/has_view.rb
155
+ - lib/arrest/helper/ids_collection.rb
157
156
  - lib/arrest/helper/logger.rb
158
157
  - lib/arrest/helper/ordered_collection.rb
159
158
  - lib/arrest/http_source.rb
@@ -1,18 +0,0 @@
1
- module Arrest
2
-
3
- class HasManyAttribute < Attribute
4
- attr_reader :method_name, :clazz_name, :url_part, :foreign_key
5
- def initialize(ids_field_name,
6
- method_name,
7
- clazz_name,
8
- url_part,
9
- foreign_key,
10
- read_only = false)
11
- super(ids_field_name, read_only, Array)
12
- @method_name = method_name.to_sym
13
- @clazz_name = clazz_name.to_sym
14
- @url_part = url_part.to_sym
15
- @foreign_key = foreign_key.to_sym
16
- end
17
- end
18
- end
@@ -1,31 +0,0 @@
1
- module Arrest
2
- class HasManySubResourceAttribute < HasManyAttribute
3
- alias :super_from_hash :from_hash
4
-
5
- def initialize(ids_field_name,
6
- method_name,
7
- clazz_name,
8
- url_part,
9
- foreign_key,
10
- read_only)
11
- # the read_only for the super constructor is set to true to avoid sending post request as ids array in JSON
12
- # directly instead of modifying the ids via the sub_resource
13
- super(ids_field_name, method_name, clazz_name, url_part, foreign_key, true)
14
- @sub_resource_read_only = read_only
15
- end
16
-
17
- def sub_resource_field_name
18
- @name
19
- end
20
-
21
- # this read only hinders the additional put to the sub resource on saving the encapsulating object
22
- def sub_resource_read_only?
23
- @sub_resource_read_only
24
- end
25
-
26
- def from_hash(parent, value)
27
- return [] if value == nil
28
- super_from_hash(parent, value)
29
- end
30
- end
31
- end