logical_model 0.4.10 → 0.5.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/README.rdoc +17 -2
- data/VERSION +1 -1
- data/client.rb +10 -4
- data/lib/logical_model.rb +23 -481
- data/lib/logical_model/api_key.rb +41 -0
- data/lib/logical_model/attributes.rb +57 -0
- data/lib/logical_model/has_many_keys.rb +53 -47
- data/lib/logical_model/rest_actions.rb +410 -0
- data/lib/logical_model/safe_log.rb +61 -0
- data/lib/logical_model/url_helper.rb +78 -0
- data/logical_model.gemspec +7 -4
- data/spec/client_spec.rb +129 -39
- metadata +8 -5
- data/lib/safe_log.rb +0 -11
- data/lib/ssl_support.rb +0 -39
@@ -0,0 +1,41 @@
|
|
1
|
+
class LogicalModel
|
2
|
+
module ApiKey
|
3
|
+
def self.included(base)
|
4
|
+
base.send(:extend, ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
attr_accessor :api_key, :api_key_name, :use_api_key
|
9
|
+
|
10
|
+
# Set api_key
|
11
|
+
# @param name [Symbol] name for api_key. Eg: app_key, token, etc.
|
12
|
+
# @param value [String] value of key. Eg: 1o2u3hqkfd, secret, etc.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# class Client < LogicalModel
|
16
|
+
# set_api_key(:token, 'asdfasdf')
|
17
|
+
# ...
|
18
|
+
# end
|
19
|
+
def set_api_key(name,value)
|
20
|
+
@use_api_key = true
|
21
|
+
@api_key_name = name
|
22
|
+
@api_key = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def use_api_key
|
26
|
+
@use_api_key ||= false
|
27
|
+
end
|
28
|
+
|
29
|
+
# if needed will merge api_key into given hash
|
30
|
+
# returns merged hash
|
31
|
+
def merge_key(params = {})
|
32
|
+
if self.use_api_key
|
33
|
+
params.merge({self.api_key_name => self.api_key})
|
34
|
+
else
|
35
|
+
params
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class LogicalModel
|
2
|
+
module Attributes
|
3
|
+
# TODO replace this module with ActvieAttr ?
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.send(:extend, ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
|
11
|
+
def attributes=(attrs)
|
12
|
+
sanitize_for_mass_assignment(attrs).each{|k,v| send("#{k}=",v) if respond_to?("#{k}=")}
|
13
|
+
end
|
14
|
+
|
15
|
+
def attributes
|
16
|
+
attrs = self.class.attribute_keys.inject(ActiveSupport::HashWithIndifferentAccess.new) do |result,key|
|
17
|
+
result[key] = read_attribute_for_validation(key)
|
18
|
+
result
|
19
|
+
end
|
20
|
+
|
21
|
+
unless self.class.has_many_keys.blank?
|
22
|
+
self.class.has_many_keys.inject(attrs) do |result,key|
|
23
|
+
result["#{key}_attributes"] = send(key).map {|a| a.attributes}
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
attrs.reject {|key, value| key == "_id" && value.blank?}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
|
33
|
+
# declares an attribute.
|
34
|
+
# @param name [Symbol]
|
35
|
+
# @example
|
36
|
+
# class Client < LogicalModel
|
37
|
+
# attribute :att_name
|
38
|
+
# end
|
39
|
+
def attribute(name)
|
40
|
+
@attribute_keys = [] if @attribute_keys.nil?
|
41
|
+
@attribute_keys << name
|
42
|
+
attr_accessor name
|
43
|
+
end
|
44
|
+
|
45
|
+
# overrides attributes with given keys.
|
46
|
+
# @param keys [Array<Symbol>]
|
47
|
+
def attribute_keys=(keys)
|
48
|
+
@attribute_keys = keys
|
49
|
+
attr_accessor *keys
|
50
|
+
end
|
51
|
+
|
52
|
+
def attribute_keys
|
53
|
+
@attribute_keys
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,69 +1,75 @@
|
|
1
1
|
class LogicalModel
|
2
2
|
module HasManyKeys
|
3
3
|
|
4
|
-
def
|
5
|
-
|
6
|
-
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:extend, ClassMethods)
|
6
|
+
end
|
7
7
|
|
8
|
-
|
8
|
+
module ClassMethods
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
instance_variable_set("@#{association}", [])
|
14
|
-
end
|
10
|
+
def has_many_keys=(keys)
|
11
|
+
@has_many_keys = keys
|
12
|
+
attr_accessor *keys
|
15
13
|
|
16
|
-
|
17
|
-
end
|
14
|
+
keys.each do |association|
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
if attr_params["_type"].present?
|
24
|
-
attr_class = attr_params.delete("_type").to_s.constantize
|
25
|
-
else
|
26
|
-
attr_class = association.to_s.singularize.camelize.constantize
|
16
|
+
# return empty array or @association variable for each association
|
17
|
+
define_method association do
|
18
|
+
if instance_variable_get("@#{association}").blank?
|
19
|
+
instance_variable_set("@#{association}", [])
|
27
20
|
end
|
28
|
-
collection << attr_class.new(attr_params)
|
29
|
-
end
|
30
|
-
instance_variable_set("@#{association}", collection)
|
31
|
-
end
|
32
21
|
|
33
|
-
|
34
|
-
if attr_params["_type"].present?
|
35
|
-
clazz = attr_params.delete(:_type).constantize
|
36
|
-
else
|
37
|
-
clazz = association.to_s.singularize.camelize.constantize
|
22
|
+
instance_variable_get("@#{association}")
|
38
23
|
end
|
39
24
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
25
|
+
# this method loads the contact attributes recieved by logical model from the service
|
26
|
+
define_method "#{association}=" do |params|
|
27
|
+
collection = []
|
28
|
+
params.each do |attr_params|
|
29
|
+
if attr_params["_type"].present?
|
30
|
+
attr_class = attr_params.delete("_type").to_s.constantize
|
31
|
+
else
|
32
|
+
attr_class = association.to_s.singularize.camelize.constantize
|
33
|
+
end
|
34
|
+
collection << attr_class.new(attr_params)
|
35
|
+
end
|
36
|
+
instance_variable_set("@#{association}", collection)
|
37
|
+
end
|
46
38
|
|
47
|
-
|
48
|
-
define_method "#{association}_attributes=" do |key_attributes|
|
49
|
-
array = []
|
50
|
-
key_attributes.each do |attr_params|
|
51
|
-
attr_params.to_hash.symbolize_keys!
|
39
|
+
define_method "new_#{association.to_s.singularize}" do |attr_params|
|
52
40
|
if attr_params["_type"].present?
|
53
|
-
|
41
|
+
clazz = attr_params.delete(:_type).constantize
|
54
42
|
else
|
55
|
-
|
43
|
+
clazz = association.to_s.singularize.camelize.constantize
|
56
44
|
end
|
57
|
-
|
45
|
+
|
46
|
+
return unless clazz
|
47
|
+
|
48
|
+
temp_object = clazz.new(attr_params.merge({"#{self.json_root}_id" => self.id}))
|
49
|
+
eval(association.to_s) << temp_object
|
50
|
+
temp_object
|
51
|
+
end
|
52
|
+
|
53
|
+
# this method loads the contact attributes from the html form (using nested resources conventions)
|
54
|
+
define_method "#{association}_attributes=" do |key_attributes|
|
55
|
+
array = []
|
56
|
+
key_attributes.each do |attr_params|
|
57
|
+
attr_params.to_hash.symbolize_keys!
|
58
|
+
if attr_params["_type"].present?
|
59
|
+
attr_class = attr_params.delete("_type").to_s.constantize
|
60
|
+
else
|
61
|
+
attr_class = association.to_s.singularize.camelize.constantize
|
62
|
+
end
|
63
|
+
array << attr_class.new(attr_params)
|
64
|
+
end
|
65
|
+
instance_variable_set("@#{association}", array)
|
58
66
|
end
|
59
|
-
instance_variable_set("@#{association}", array)
|
60
67
|
end
|
61
68
|
end
|
62
|
-
end
|
63
69
|
|
64
|
-
|
65
|
-
|
70
|
+
def has_many_keys
|
71
|
+
@has_many_keys
|
72
|
+
end
|
66
73
|
end
|
67
|
-
|
68
74
|
end
|
69
75
|
end
|
@@ -0,0 +1,410 @@
|
|
1
|
+
class LogicalModel
|
2
|
+
module RESTActions
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.send(:extend, ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
|
11
|
+
def create(params={})
|
12
|
+
run_callbacks :save do
|
13
|
+
run_callbacks :create do
|
14
|
+
_create(params)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def save
|
20
|
+
run_callbacks :save do
|
21
|
+
run_callbacks new_record?? :create : :update do
|
22
|
+
_save
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroy(params={})
|
28
|
+
run_callbacks :destroy do
|
29
|
+
_destroy(params)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param params [Hash] parameters to be sent to service
|
34
|
+
def update(params)
|
35
|
+
run_callbacks :save do
|
36
|
+
run_callbacks :update do
|
37
|
+
_update(params)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# creates model.
|
45
|
+
#
|
46
|
+
# returns:
|
47
|
+
# @return false if model invalid
|
48
|
+
# @return nil if there was a connection problem
|
49
|
+
# @return created model ID if successfull
|
50
|
+
#
|
51
|
+
# @example Usage:
|
52
|
+
# @person = Person.new(params[:person])
|
53
|
+
# @person.create( non_attribute_param: "value" )
|
54
|
+
def _create(params = {})
|
55
|
+
return false unless valid?
|
56
|
+
|
57
|
+
params = { self.json_root => self.attributes }.merge(params)
|
58
|
+
params = self.class.merge_key(params)
|
59
|
+
|
60
|
+
response = nil
|
61
|
+
Timeout::timeout(self.class.timeout/1000) do
|
62
|
+
response = Typhoeus::Request.post( self.class.resource_uri, :body => params, :timeout => self.class.timeout )
|
63
|
+
end
|
64
|
+
self.last_response_code = response.code
|
65
|
+
if response.code == 201 || response.code == 202
|
66
|
+
log_ok(response)
|
67
|
+
if self.respond_to?('id=')
|
68
|
+
self.id = ActiveSupport::JSON.decode(response.body)["id"]
|
69
|
+
else
|
70
|
+
true
|
71
|
+
end
|
72
|
+
elsif response.code == 400
|
73
|
+
log_failed(response)
|
74
|
+
ws_errors = ActiveSupport::JSON.decode(response.body)["errors"]
|
75
|
+
ws_errors.each_key do |k|
|
76
|
+
self.errors.add k, ws_errors[k]
|
77
|
+
end
|
78
|
+
return false
|
79
|
+
else
|
80
|
+
log_failed(response)
|
81
|
+
return nil
|
82
|
+
end
|
83
|
+
rescue Timeout::Error
|
84
|
+
self.class.logger.warn "timeout"
|
85
|
+
return nil
|
86
|
+
end
|
87
|
+
|
88
|
+
# Updates Objects attributes, this will only send attributes passed as arguments
|
89
|
+
#
|
90
|
+
#
|
91
|
+
# Returns false if Object#valid? is false.
|
92
|
+
# Returns updated object if successfull.
|
93
|
+
# Returns nil if update failed
|
94
|
+
#
|
95
|
+
# Usage:
|
96
|
+
# @person.update(params[:person])
|
97
|
+
def _update(params)
|
98
|
+
|
99
|
+
self.attributes = params[self.json_root]
|
100
|
+
|
101
|
+
return false unless valid?
|
102
|
+
|
103
|
+
params = self.class.merge_key(params)
|
104
|
+
|
105
|
+
response = nil
|
106
|
+
Timeout::timeout(self.class.timeout/1000) do
|
107
|
+
response = Typhoeus::Request.put( self.class.resource_uri(id),
|
108
|
+
:params => params,
|
109
|
+
:timeout => self.class.timeout )
|
110
|
+
end
|
111
|
+
|
112
|
+
if response.code == 200
|
113
|
+
log_ok(response)
|
114
|
+
return self
|
115
|
+
else
|
116
|
+
log_failed(response)
|
117
|
+
return nil
|
118
|
+
end
|
119
|
+
|
120
|
+
rescue Timeout::Error
|
121
|
+
self.class.logger.warn("request timed out")
|
122
|
+
return nil
|
123
|
+
end
|
124
|
+
|
125
|
+
# Saves Objects attributes
|
126
|
+
#
|
127
|
+
#
|
128
|
+
# Returns false if Object#valid? is false.
|
129
|
+
# Returns updated object if successfull.
|
130
|
+
# Returns nil if update failed
|
131
|
+
#
|
132
|
+
# Usage:
|
133
|
+
# @person.save
|
134
|
+
def _save
|
135
|
+
self.attributes = attributes
|
136
|
+
|
137
|
+
return false unless valid?
|
138
|
+
|
139
|
+
sending_params = self.attributes
|
140
|
+
sending_params.delete(:id)
|
141
|
+
|
142
|
+
params = { self.json_root => sending_params }
|
143
|
+
params = self.class.merge_key(params)
|
144
|
+
response = nil
|
145
|
+
Timeout::timeout(self.class.timeout/1000) do
|
146
|
+
response = Typhoeus::Request.put( self.class.resource_uri(id), :params => params, :timeout => self.class.timeout )
|
147
|
+
end
|
148
|
+
if response.code == 200
|
149
|
+
log_ok(response)
|
150
|
+
return self
|
151
|
+
else
|
152
|
+
log_failed(response)
|
153
|
+
return nil
|
154
|
+
end
|
155
|
+
rescue Timeout::Error
|
156
|
+
self.class.logger.warn "timeout"
|
157
|
+
return nil
|
158
|
+
end
|
159
|
+
|
160
|
+
# Destroy object
|
161
|
+
#
|
162
|
+
# Usage:
|
163
|
+
# @person.destroy
|
164
|
+
def _destroy(params={})
|
165
|
+
self.class.delete(self.id,params)
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
module ClassMethods
|
171
|
+
|
172
|
+
attr_accessor :enable_delete_multiple
|
173
|
+
|
174
|
+
# ============================================================================================================
|
175
|
+
# Following methods are API specific.
|
176
|
+
# They assume we are using a RESTfull API.
|
177
|
+
# for get, put, delete :id is expected
|
178
|
+
# for post, put attributes are excepted under class_name directly. eg. put( {:id => 1, :class_name => {:attr => "new value for attr"}} )
|
179
|
+
#
|
180
|
+
# On error (400) a "errors" is expected.
|
181
|
+
# ============================================================================================================
|
182
|
+
|
183
|
+
# Asynchronic Pagination
|
184
|
+
# This pagination won't block excecution waiting for result, pagination will be enqueued in Objectr#hydra.
|
185
|
+
#
|
186
|
+
# Parameters:
|
187
|
+
# @param options [Hash].
|
188
|
+
# Valid options are:
|
189
|
+
# * :page - indicated what page to return. Defaults to 1.
|
190
|
+
# * :per_page - indicates how many records to be returned per page. Defauls to 20
|
191
|
+
# * all other options will be sent in :params to WebService
|
192
|
+
#
|
193
|
+
# Usage:
|
194
|
+
# Person.async_paginate(:page => params[:page]){|i| result = i}
|
195
|
+
def async_paginate(options={})
|
196
|
+
options[:page] ||= 1
|
197
|
+
options[:per_page] ||= 20
|
198
|
+
|
199
|
+
options = self.merge_key(options)
|
200
|
+
|
201
|
+
request = Typhoeus::Request.new(resource_uri, :params => options)
|
202
|
+
request.on_complete do |response|
|
203
|
+
if response.code >= 200 && response.code < 400
|
204
|
+
log_ok(response)
|
205
|
+
|
206
|
+
result_set = self.from_json(response.body)
|
207
|
+
|
208
|
+
# this paginate is will_paginate's Array pagination
|
209
|
+
collection = Kaminari.paginate_array(
|
210
|
+
result_set[:collection],
|
211
|
+
{
|
212
|
+
:total_count=>result_set[:total],
|
213
|
+
:limit => options[:per_page],
|
214
|
+
:offset => options[:per_page] * ([options[:page], 1].max - 1)
|
215
|
+
}
|
216
|
+
)
|
217
|
+
|
218
|
+
yield collection
|
219
|
+
else
|
220
|
+
log_failed(response)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
self.hydra.queue(request)
|
224
|
+
end
|
225
|
+
|
226
|
+
#synchronic pagination
|
227
|
+
def paginate(options={})
|
228
|
+
result = nil
|
229
|
+
self.retries.times do
|
230
|
+
begin
|
231
|
+
async_paginate(options){|i| result = i}
|
232
|
+
Timeout::timeout(self.timeout/1000) do
|
233
|
+
self.hydra.run
|
234
|
+
end
|
235
|
+
break unless result.nil?
|
236
|
+
rescue Timeout::Error
|
237
|
+
self.logger.warn("timeout")
|
238
|
+
result = nil
|
239
|
+
end
|
240
|
+
end
|
241
|
+
result
|
242
|
+
end
|
243
|
+
|
244
|
+
# Asynchronic Count
|
245
|
+
# This count won't block excecution waiting for result, count will be enqueued in Objectr#hydra.
|
246
|
+
#
|
247
|
+
# Parameters:
|
248
|
+
# @param options [Hash].
|
249
|
+
# Valid options are:
|
250
|
+
# @option options [Integer] :page - indicated what page to return. Defaults to 1.
|
251
|
+
# @option options [Integer] :per_page - indicates how many records to be returned per page. Defauls to 20
|
252
|
+
# @option options [Hash] all other options will be forwarded in :params to WebService
|
253
|
+
#
|
254
|
+
# @example 'Count bobs'
|
255
|
+
# Person.async_count(:when => {:name => 'bob'}}){|i| result = i}
|
256
|
+
def async_count(options={})
|
257
|
+
options[:page] = 1
|
258
|
+
options[:per_page] = 1
|
259
|
+
|
260
|
+
options = self.merge_key(options)
|
261
|
+
|
262
|
+
request = Typhoeus::Request.new(resource_uri, :params => options)
|
263
|
+
request.on_complete do |response|
|
264
|
+
if response.code >= 200 && response.code < 400
|
265
|
+
log_ok(response)
|
266
|
+
|
267
|
+
result_set = self.from_json(response.body)
|
268
|
+
|
269
|
+
yield result_set[:total]
|
270
|
+
else
|
271
|
+
log_failed(response)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
self.hydra.queue(request)
|
275
|
+
end
|
276
|
+
|
277
|
+
# synchronic count
|
278
|
+
def count(options={})
|
279
|
+
result = nil
|
280
|
+
async_count(options){|i| result = i}
|
281
|
+
Timeout::timeout(self.timeout/1000) do
|
282
|
+
self.hydra.run
|
283
|
+
end
|
284
|
+
result
|
285
|
+
rescue Timeout::Error
|
286
|
+
self.logger.warn("timeout")
|
287
|
+
return nil
|
288
|
+
end
|
289
|
+
|
290
|
+
# Asynchronic Find
|
291
|
+
# This find won't block excecution waiting for result, excecution will be enqueued in Objectr#hydra.
|
292
|
+
#
|
293
|
+
# Parameters:
|
294
|
+
# - id, id of object to find
|
295
|
+
# @param [String/Integer] id
|
296
|
+
# @param [Hash] params
|
297
|
+
#
|
298
|
+
# Usage:
|
299
|
+
# Person.async_find(params[:id])
|
300
|
+
def async_find(id, params = {})
|
301
|
+
params = self.merge_key(params)
|
302
|
+
request = Typhoeus::Request.new( resource_uri(id), :params => params )
|
303
|
+
|
304
|
+
request.on_complete do |response|
|
305
|
+
if response.code >= 200 && response.code < 400
|
306
|
+
log_ok(response)
|
307
|
+
yield self.new.from_json(response.body) # this from_json is defined in ActiveModel::Serializers::JSON
|
308
|
+
else
|
309
|
+
log_failed(response)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
self.hydra.queue(request)
|
314
|
+
end
|
315
|
+
|
316
|
+
# synchronic find
|
317
|
+
def find(id, params = {})
|
318
|
+
result = nil
|
319
|
+
async_find(id, params){|i| result = i}
|
320
|
+
Timeout::timeout(self.timeout/1000) do
|
321
|
+
self.hydra.run
|
322
|
+
end
|
323
|
+
result
|
324
|
+
rescue Timeout::Error
|
325
|
+
self.logger.warn("timeout")
|
326
|
+
return nil
|
327
|
+
end
|
328
|
+
|
329
|
+
# Deletes Object#id
|
330
|
+
#
|
331
|
+
# Returns nil if delete failed
|
332
|
+
#
|
333
|
+
# @param [String] id - id of contact to be deleted
|
334
|
+
# @param [Hash] params - other params to be sent to WS on request
|
335
|
+
#
|
336
|
+
# Usage:
|
337
|
+
# Person.delete(params[:id])
|
338
|
+
def delete(id, params={})
|
339
|
+
|
340
|
+
params = self.merge_key(params)
|
341
|
+
|
342
|
+
response = nil
|
343
|
+
Timeout::timeout(self.timeout/1000) do
|
344
|
+
response = Typhoeus::Request.delete( self.resource_uri(id),
|
345
|
+
:params => params,
|
346
|
+
:timeout => self.timeout
|
347
|
+
)
|
348
|
+
end
|
349
|
+
if response.code == 200
|
350
|
+
log_ok(response)
|
351
|
+
return self
|
352
|
+
else
|
353
|
+
log_failed(response)
|
354
|
+
return nil
|
355
|
+
end
|
356
|
+
rescue Timeout::Error
|
357
|
+
self.logger.warn "timeout"
|
358
|
+
return nil
|
359
|
+
end
|
360
|
+
|
361
|
+
# Deletes all Objects matching given ids
|
362
|
+
#
|
363
|
+
# This method will make a DELETE request to resource_uri/destroy_multiple
|
364
|
+
#
|
365
|
+
# Returns nil if delete failed
|
366
|
+
#
|
367
|
+
# @param [Array] ids - ids of contacts to be deleted
|
368
|
+
# @param [Hash] params - other params to be sent to WS on request
|
369
|
+
#
|
370
|
+
# Usage:
|
371
|
+
# Person.delete_multiple([1,2,4,5,6])
|
372
|
+
def delete_multiple(ids, params={})
|
373
|
+
raise "not-enabled" unless self.delete_multiple_enabled?
|
374
|
+
|
375
|
+
params = self.merge_key(params)
|
376
|
+
params = params.merge({:ids => ids})
|
377
|
+
|
378
|
+
response = nil
|
379
|
+
Timeout::timeout(self.timeout/1000) do
|
380
|
+
response = Typhoeus::Request.delete( self.resource_uri+"/destroy_multiple",
|
381
|
+
:params => params,
|
382
|
+
:timeout => self.timeout
|
383
|
+
)
|
384
|
+
end
|
385
|
+
if response.code == 200
|
386
|
+
log_ok(response)
|
387
|
+
return self
|
388
|
+
else
|
389
|
+
log_failed(response)
|
390
|
+
return nil
|
391
|
+
end
|
392
|
+
rescue Timeout::Error
|
393
|
+
self.logger.warn "timeout"
|
394
|
+
return nil
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
##
|
400
|
+
# Will parse JSON string and initialize classes for all hashes in json_string[collection].
|
401
|
+
#
|
402
|
+
# @param json_string [JSON String] This JSON should have format: {collection: [...], total: X}
|
403
|
+
#
|
404
|
+
def self.from_json(json_string)
|
405
|
+
parsed = ActiveSupport::JSON.decode(json_string)
|
406
|
+
collection = parsed["collection"].map{|i|self.new(i)}
|
407
|
+
return { :collection => collection, :total => parsed["total"].to_i }
|
408
|
+
end
|
409
|
+
|
410
|
+
end
|