arrest 0.0.67 → 0.0.68
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/lib/arrest.rb +1 -2
- data/lib/arrest/abstract_resource.rb +4 -29
- data/lib/arrest/attributes/belongs_to.rb +12 -10
- data/lib/arrest/attributes/has_attributes.rb +4 -18
- data/lib/arrest/helper/has_many.rb +25 -42
- data/lib/arrest/helper/ids_collection.rb +31 -0
- data/lib/arrest/helper/ordered_collection.rb +14 -0
- data/lib/arrest/http_source.rb +3 -0
- data/lib/arrest/mem_source.rb +1 -1
- data/lib/arrest/version.rb +1 -1
- metadata +23 -24
- data/lib/arrest/attributes/has_many_attribute.rb +0 -18
- data/lib/arrest/attributes/has_many_sub_resource_attribute.rb +0 -31
data/lib/arrest.rb
CHANGED
@@ -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
|
-
|
237
|
-
|
238
|
-
|
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
|
48
|
+
if val.blank?
|
49
49
|
return nil
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
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
|
-
|
13
|
-
method_name = method_name.to_sym
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
|
data/lib/arrest/http_source.rb
CHANGED
@@ -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
|
data/lib/arrest/mem_source.rb
CHANGED
data/lib/arrest/version.rb
CHANGED
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.
|
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-
|
12
|
+
date: 2012-06-20 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
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: *
|
24
|
+
version_requirements: *25743060
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: faraday
|
27
|
-
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: *
|
35
|
+
version_requirements: *25742560
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activemodel
|
38
|
-
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: *
|
46
|
+
version_requirements: *25742060
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
|
-
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: *
|
57
|
+
version_requirements: *25741600
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
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: *
|
68
|
+
version_requirements: *25741220
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rdoc
|
71
|
-
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: *
|
79
|
+
version_requirements: *25740760
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rspec
|
82
|
-
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: *
|
90
|
+
version_requirements: *25740260
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: rr
|
93
|
-
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: *
|
101
|
+
version_requirements: *25739840
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: simplecov
|
104
|
-
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: *
|
112
|
+
version_requirements: *25739380
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: rack
|
115
|
-
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: *
|
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
|