jsonapi_compliable 0.6.4 → 0.6.5

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +11 -3
  4. data/.yardopts +1 -0
  5. data/README.md +10 -1
  6. data/Rakefile +1 -0
  7. data/docs/JsonapiCompliable.html +202 -0
  8. data/docs/JsonapiCompliable/Adapters.html +119 -0
  9. data/docs/JsonapiCompliable/Adapters/Abstract.html +2285 -0
  10. data/docs/JsonapiCompliable/Adapters/ActiveRecord.html +2151 -0
  11. data/docs/JsonapiCompliable/Adapters/ActiveRecordSideloading.html +582 -0
  12. data/docs/JsonapiCompliable/Adapters/Null.html +1682 -0
  13. data/docs/JsonapiCompliable/Base.html +1395 -0
  14. data/docs/JsonapiCompliable/Deserializer.html +835 -0
  15. data/docs/JsonapiCompliable/Errors.html +115 -0
  16. data/docs/JsonapiCompliable/Errors/BadFilter.html +124 -0
  17. data/docs/JsonapiCompliable/Errors/StatNotFound.html +266 -0
  18. data/docs/JsonapiCompliable/Errors/UnsupportedPageSize.html +264 -0
  19. data/docs/JsonapiCompliable/Errors/ValidationError.html +124 -0
  20. data/docs/JsonapiCompliable/Extensions.html +117 -0
  21. data/docs/JsonapiCompliable/Extensions/BooleanAttribute.html +212 -0
  22. data/docs/JsonapiCompliable/Extensions/BooleanAttribute/ClassMethods.html +229 -0
  23. data/docs/JsonapiCompliable/Extensions/ExtraAttribute.html +242 -0
  24. data/docs/JsonapiCompliable/Extensions/ExtraAttribute/ClassMethods.html +237 -0
  25. data/docs/JsonapiCompliable/Query.html +1099 -0
  26. data/docs/JsonapiCompliable/Rails.html +211 -0
  27. data/docs/JsonapiCompliable/Resource.html +5241 -0
  28. data/docs/JsonapiCompliable/Scope.html +703 -0
  29. data/docs/JsonapiCompliable/Scoping.html +117 -0
  30. data/docs/JsonapiCompliable/Scoping/Base.html +843 -0
  31. data/docs/JsonapiCompliable/Scoping/DefaultFilter.html +318 -0
  32. data/docs/JsonapiCompliable/Scoping/ExtraFields.html +301 -0
  33. data/docs/JsonapiCompliable/Scoping/Filter.html +313 -0
  34. data/docs/JsonapiCompliable/Scoping/Filterable.html +364 -0
  35. data/docs/JsonapiCompliable/Scoping/Paginate.html +613 -0
  36. data/docs/JsonapiCompliable/Scoping/Sort.html +454 -0
  37. data/docs/JsonapiCompliable/SerializableTempId.html +216 -0
  38. data/docs/JsonapiCompliable/Sideload.html +2484 -0
  39. data/docs/JsonapiCompliable/Stats.html +117 -0
  40. data/docs/JsonapiCompliable/Stats/DSL.html +999 -0
  41. data/docs/JsonapiCompliable/Stats/Payload.html +391 -0
  42. data/docs/JsonapiCompliable/Util.html +117 -0
  43. data/docs/JsonapiCompliable/Util/FieldParams.html +228 -0
  44. data/docs/JsonapiCompliable/Util/Hash.html +471 -0
  45. data/docs/JsonapiCompliable/Util/IncludeParams.html +299 -0
  46. data/docs/JsonapiCompliable/Util/Persistence.html +435 -0
  47. data/docs/JsonapiCompliable/Util/RelationshipPayload.html +563 -0
  48. data/docs/JsonapiCompliable/Util/RenderOptions.html +250 -0
  49. data/docs/JsonapiCompliable/Util/ValidationResponse.html +532 -0
  50. data/docs/_index.html +527 -0
  51. data/docs/class_list.html +51 -0
  52. data/docs/css/common.css +1 -0
  53. data/docs/css/full_list.css +58 -0
  54. data/docs/css/style.css +492 -0
  55. data/docs/file.README.html +99 -0
  56. data/docs/file_list.html +56 -0
  57. data/docs/frames.html +17 -0
  58. data/docs/index.html +99 -0
  59. data/docs/js/app.js +248 -0
  60. data/docs/js/full_list.js +216 -0
  61. data/docs/js/jquery.js +4 -0
  62. data/docs/method_list.html +1731 -0
  63. data/docs/top-level-namespace.html +110 -0
  64. data/gemfiles/rails_5.gemfile +1 -1
  65. data/lib/jsonapi_compliable/adapters/abstract.rb +267 -4
  66. data/lib/jsonapi_compliable/adapters/active_record.rb +23 -1
  67. data/lib/jsonapi_compliable/adapters/null.rb +43 -3
  68. data/lib/jsonapi_compliable/base.rb +182 -33
  69. data/lib/jsonapi_compliable/deserializer.rb +90 -21
  70. data/lib/jsonapi_compliable/extensions/boolean_attribute.rb +12 -0
  71. data/lib/jsonapi_compliable/extensions/extra_attribute.rb +32 -0
  72. data/lib/jsonapi_compliable/extensions/temp_id.rb +11 -0
  73. data/lib/jsonapi_compliable/query.rb +94 -2
  74. data/lib/jsonapi_compliable/rails.rb +8 -0
  75. data/lib/jsonapi_compliable/resource.rb +548 -11
  76. data/lib/jsonapi_compliable/scope.rb +43 -1
  77. data/lib/jsonapi_compliable/scoping/base.rb +59 -8
  78. data/lib/jsonapi_compliable/scoping/default_filter.rb +33 -0
  79. data/lib/jsonapi_compliable/scoping/extra_fields.rb +33 -0
  80. data/lib/jsonapi_compliable/scoping/filter.rb +29 -2
  81. data/lib/jsonapi_compliable/scoping/filterable.rb +4 -0
  82. data/lib/jsonapi_compliable/scoping/paginate.rb +33 -0
  83. data/lib/jsonapi_compliable/scoping/sort.rb +18 -0
  84. data/lib/jsonapi_compliable/sideload.rb +229 -1
  85. data/lib/jsonapi_compliable/stats/dsl.rb +44 -0
  86. data/lib/jsonapi_compliable/stats/payload.rb +20 -0
  87. data/lib/jsonapi_compliable/util/field_params.rb +1 -0
  88. data/lib/jsonapi_compliable/util/hash.rb +18 -0
  89. data/lib/jsonapi_compliable/util/include_params.rb +22 -0
  90. data/lib/jsonapi_compliable/util/persistence.rb +13 -3
  91. data/lib/jsonapi_compliable/util/relationship_payload.rb +2 -0
  92. data/lib/jsonapi_compliable/util/render_options.rb +2 -0
  93. data/lib/jsonapi_compliable/util/validation_response.rb +16 -0
  94. data/lib/jsonapi_compliable/version.rb +1 -1
  95. metadata +60 -5
  96. data/gemfiles/rails_4.gemfile.lock +0 -208
  97. data/gemfiles/rails_5.gemfile.lock +0 -212
  98. data/lib/jsonapi_compliable/write.rb +0 -93
@@ -0,0 +1,110 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.9.9
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ pathId = "";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+
41
+
42
+ <span class="title">Top Level Namespace</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Top Level Namespace
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+ </div>
80
+
81
+ <h2>Defined Under Namespace</h2>
82
+ <p class="children">
83
+
84
+
85
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="JsonapiCompliable.html" title="JsonapiCompliable (module)">JsonapiCompliable</a></span>
86
+
87
+
88
+
89
+
90
+ </p>
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+ </div>
101
+
102
+ <div id="footer">
103
+ Generated on Fri May 5 15:53:21 2017 by
104
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
+ 0.9.9 (ruby-2.3.0).
106
+ </div>
107
+
108
+ </div>
109
+ </body>
110
+ </html>
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.0"
5
+ gem "rails", ['>= 5.0', '< 5.1']
6
6
  gem "jsonapi-rails", "~> 0.1", :require => "jsonapi/rails"
7
7
  gem "rspec-rails"
8
8
 
@@ -1,33 +1,296 @@
1
1
  module JsonapiCompliable
2
2
  module Adapters
3
+ # Adapters DRY up common resource logic.
4
+ #
5
+ # For instance, there's no reason to write ActiveRecord logic like this in
6
+ # every Resource:
7
+ #
8
+ # allow_filter :title do |scope, value|
9
+ # scope.where(title: value)
10
+ # end
11
+ #
12
+ # sort do |scope, att, dir|
13
+ # scope.order(att => dir)
14
+ # end
15
+ #
16
+ # paginate do |scope, current_page, per_page|
17
+ # scope.page(current_page).per(per_page)
18
+ # end
19
+ #
20
+ # This logic can be re-used through an *Adapter*:
21
+ #
22
+ # use_adapter JsonapiCompliable::Adapters::ActiveRecord
23
+ # allow_filter :title
24
+ #
25
+ # Adapters are pretty simple to write. The corresponding code for the above
26
+ # ActiveRecord adapter, which should look pretty familiar:
27
+ #
28
+ # class JsonapiCompliable::Adapters::ActiveRecord
29
+ # def filter(scope, attribute, value)
30
+ # scope.where(attribute => value)
31
+ # end
32
+ #
33
+ # def order(scope, attribute, direction)
34
+ # scope.order(attribute => direction)
35
+ # end
36
+ #
37
+ # def paginate(scope, current_page, per_page)
38
+ # scope.page(current_page).per(per_page)
39
+ # end
40
+ # end
41
+ #
42
+ # An adapter can have a corresponding +sideloading_module+. This module
43
+ # gets mixed in to a Sideload. In other words, *Resource* is to
44
+ # *Adapter* as *Sideload* is to *Adapter#sideloading_module*. Use this
45
+ # module to define DSL methods that wrap #allow_sideload:
46
+ #
47
+ # class MyAdapter < JsonapiCompliable::Adapters::Abstract
48
+ # # ... code ...
49
+ # def sideloading_module
50
+ # MySideloadingAdapter
51
+ # end
52
+ # end
53
+ #
54
+ # module MySideloadingAdapter
55
+ # def belongs_to(association_name)
56
+ # allow_sideload association_name do
57
+ # # ... code ...
58
+ # end
59
+ # end
60
+ # end
61
+ #
62
+ # # And now in your Resource:
63
+ # class MyResource < ApplicationResource
64
+ # # ... code ...
65
+ # use_adapter MyAdapter
66
+ #
67
+ # belongs_to :my_association
68
+ # end
69
+ #
70
+ # If you need the adapter to do *nothing*, because perhaps the API you
71
+ # are hitting does not support sorting,
72
+ # use +JsonapiCompliable::Adapters::Null+.
73
+ #
74
+ # @see Resource.use_adapter
75
+ # @see Adapters::ActiveRecord
76
+ # @see Adapters::ActiveRecordSideloading
77
+ # @see Adapters::Null
3
78
  class Abstract
79
+ # @param scope The scope object we are chaining
80
+ # @param [Symbol] attribute The attribute name we are filtering
81
+ # @param value The corresponding query parameter value
82
+ # @return the scope
83
+ #
84
+ # @example ActiveRecord default
85
+ # def filter(scope, attribute, value)
86
+ # scope.where(attribute => value)
87
+ # end
4
88
  def filter(scope, attribute, value)
5
89
  raise 'you must override #filter in an adapter subclass'
6
90
  end
7
91
 
92
+ # @param scope The scope object we are chaining
93
+ # @param [Symbol] attribute The attribute name we are sorting
94
+ # @param [Symbol] direction The direction we are sorting (asc/desc)
95
+ # @return the scope
96
+ #
97
+ # @example ActiveRecord default
98
+ # def order(scope, attribute, direction)
99
+ # scope.order(attribute => direction)
100
+ # end
8
101
  def order(scope, attribute, direction)
9
102
  raise 'you must override #order in an adapter subclass'
10
103
  end
11
104
 
12
- def paginate(scope, number, size)
105
+ # @param scope The scope object we are chaining
106
+ # @param [Integer] current_page The current page number
107
+ # @param [Integer] per_page The number of results per page
108
+ # @return the scope
109
+ #
110
+ # @example ActiveRecord default
111
+ # # via kaminari gem
112
+ # def paginate(scope, current_page, per_page)
113
+ # scope.page(current_page).per(per_page)
114
+ # end
115
+ def paginate(scope, current_page, per_page)
13
116
  raise 'you must override #paginate in an adapter subclass'
14
117
  end
15
118
 
16
- def sideload(scope, includes)
17
- raise 'you must override #sideload in an adapter subclass'
119
+ # @param scope the scope object we are chaining
120
+ # @param [Symbol] attr corresponding stat attribute name
121
+ # @return [Numeric] the count of the scope
122
+ # @example ActiveRecord default
123
+ # def count(scope, attr)
124
+ # column = attr == :total ? :all : attr
125
+ # scope.uniq.count(column)
126
+ # end
127
+ def count(scope, attr)
128
+ raise 'you must override #count in an adapter subclass'
18
129
  end
19
130
 
20
- def transaction
131
+ # @param scope the scope object we are chaining
132
+ # @param [Symbol] attr corresponding stat attribute name
133
+ # @return [Float] the average of the scope
134
+ # @example ActiveRecord default
135
+ # def average(scope, attr)
136
+ # scope.average(attr).to_f
137
+ # end
138
+ def average(scope, attr)
139
+ raise 'you must override #average in an adapter subclass'
140
+ end
141
+
142
+ # @param scope the scope object we are chaining
143
+ # @param [Symbol] attr corresponding stat attribute name
144
+ # @return [Numeric] the sum of the scope
145
+ # @example ActiveRecord default
146
+ # def sum(scope, attr)
147
+ # scope.sum(attr)
148
+ # end
149
+ def sum(scope, attr)
150
+ raise 'you must override #sum in an adapter subclass'
151
+ end
152
+
153
+ # @param scope the scope object we are chaining
154
+ # @param [Symbol] attr corresponding stat attribute name
155
+ # @return [Numeric] the maximum value of the scope
156
+ # @example ActiveRecord default
157
+ # def maximum(scope, attr)
158
+ # scope.maximum(attr)
159
+ # end
160
+ def maximum(scope, attr)
161
+ raise 'you must override #maximum in an adapter subclass'
162
+ end
163
+
164
+ # @param scope the scope object we are chaining
165
+ # @param [Symbol] attr corresponding stat attribute name
166
+ # @return [Numeric] the maximum value of the scope
167
+ # @example ActiveRecord default
168
+ # def maximum(scope, attr)
169
+ # scope.maximum(attr)
170
+ # end
171
+ def minimum(scope, attr)
172
+ raise 'you must override #maximum in an adapter subclass'
173
+ end
174
+
175
+ # This method must +yield+ the code to run within the transaction.
176
+ # This method should roll back the transaction if an error is raised.
177
+ #
178
+ # @param [Class] model_class The class we're operating on
179
+ # @example ActiveRecord default
180
+ # def transaction(model_class)
181
+ # model_class.transaction do
182
+ # yield
183
+ # end
184
+ # end
185
+ #
186
+ # @see Resource.model
187
+ def transaction(model_class)
21
188
  raise 'you must override #transaction in an adapter subclass, it must yield'
22
189
  end
23
190
 
191
+ # Resolve the scope. This is where you'd actually fire SQL,
192
+ # actually make an HTTP call, etc.
193
+ #
194
+ # @example ActiveRecordDefault
195
+ # def resolve(scope)
196
+ # scope.to_a
197
+ # end
198
+ #
199
+ # @example Suggested Customization
200
+ # # When making a service call, we suggest this abstraction
201
+ # # 'scope' here is a hash
202
+ # def resolve(scope)
203
+ # # The implementation of .where can be whatever you want
204
+ # SomeModelClass.where(scope)
205
+ # end
206
+ #
207
+ # @see Adapters::ActiveRecord#resolve
208
+ # @param scope The scope object to resolve
209
+ # @return an array of Model instances
24
210
  def resolve(scope)
25
211
  scope
26
212
  end
27
213
 
214
+ # Assign these two objects together.
215
+ #
216
+ # @example Basic accessor
217
+ # def associate(parent, child, association_name, association_type)
218
+ # if association_type == :has_many
219
+ # parent.send(association_name).push(child)
220
+ # else
221
+ # child.send(:"#{association_name}=", parent)
222
+ # end
223
+ # end
224
+ #
225
+ # +association_name+ and +association_type+ come from your sideload
226
+ # configuration:
227
+ #
228
+ # allow_sideload :the_name, type: the_type do
229
+ # # ... code.
230
+ # end
231
+ #
232
+ # @param parent The parent object (via the JSONAPI 'relationships' graph)
233
+ # @param child The child object (via the JSONAPI 'relationships' graph)
234
+ # @param association_name The 'relationships' key we are processing
235
+ # @param association_type The Sideload type (see Sideload#type). Usually :has_many/:belongs_to/etc
236
+ def associate(parent, child, association_name, association_type)
237
+ raise 'you must override #associate in an adapter subclass'
238
+ end
239
+
240
+ # This module gets mixed in to Sideload classes
241
+ # This is where you define methods like has_many,
242
+ # belongs_to etc that wrap the lower-level Sideload#allow_sideload
243
+ #
244
+ # @see Resource#allow_sideload
245
+ # @see Sideload#allow_sideload
246
+ # @see Adapters::ActiveRecord#sideloading_module
247
+ # @see Adapters::ActiveRecordSideloading
248
+ # @return the module to mix in
28
249
  def sideloading_module
29
250
  Module.new
30
251
  end
252
+
253
+ # @param [Class] model_class The configured model class (see Resource.model)
254
+ # @param [Hash] create_params Attributes + id
255
+ # @return the model instance just created
256
+ # @see Resource.model
257
+ # @example ActiveRecord default
258
+ # def create(model_class, create_params)
259
+ # instance = model_class.new(create_params)
260
+ # instance.save
261
+ # instance
262
+ # end
263
+ def create(model_class, create_params)
264
+ raise 'you must override #create in an adapter subclass'
265
+ end
266
+
267
+ # @param [Class] model_class The configured model class (see Resource.model)
268
+ # @param [Hash] update_params Attributes + id
269
+ # @return the model instance just created
270
+ # @see Resource.model
271
+ # @example ActiveRecord default
272
+ # def update(model_class, update_params)
273
+ # instance = model_class.find(update_params.delete(:id))
274
+ # instance.update_attributes(update_params)
275
+ # instance
276
+ # end
277
+ def update(model_class, update_params)
278
+ raise 'you must override #update in an adapter subclass'
279
+ end
280
+
281
+ # @param [Class] model_class The configured model class (see Resource.model)
282
+ # @param [Integer] id the id for this model
283
+ # @return the model instance just destroyed
284
+ # @see Resource.model
285
+ # @example ActiveRecord default
286
+ # def destroy(model_class, id)
287
+ # instance = model_class.find(id)
288
+ # instance.destroy
289
+ # instance
290
+ # end
291
+ def destroy(model_class, id)
292
+ raise 'you must override #destroy in an adapter subclass'
293
+ end
31
294
  end
32
295
  end
33
296
  end
@@ -2,53 +2,72 @@ require 'jsonapi_compliable/adapters/active_record_sideloading'
2
2
 
3
3
  module JsonapiCompliable
4
4
  module Adapters
5
+ # @see Adapters::Abstract
5
6
  class ActiveRecord < Abstract
7
+ # (see Adapters::Abstract#filter)
6
8
  def filter(scope, attribute, value)
7
9
  scope.where(attribute => value)
8
10
  end
9
11
 
12
+ # (see Adapters::Abstract#order)
10
13
  def order(scope, attribute, direction)
11
14
  scope.order(attribute => direction)
12
15
  end
13
16
 
17
+ # (see Adapters::Abstract#paginate)
14
18
  def paginate(scope, current_page, per_page)
15
19
  scope.page(current_page).per(per_page)
16
20
  end
17
21
 
22
+ # (see Adapters::Abstract#count)
18
23
  def count(scope, attr)
19
- scope.uniq.count
24
+ column = attr == :total ? :all : attr
25
+ scope.uniq.count(column)
20
26
  end
21
27
 
28
+ # (see Adapters::Abstract#average)
22
29
  def average(scope, attr)
23
30
  scope.average(attr).to_f
24
31
  end
25
32
 
33
+ # (see Adapters::Abstract#sum)
26
34
  def sum(scope, attr)
27
35
  scope.sum(attr)
28
36
  end
29
37
 
38
+ # (see Adapters::Abstract#maximum)
30
39
  def maximum(scope, attr)
31
40
  scope.maximum(attr)
32
41
  end
33
42
 
43
+ # (see Adapters::Abstract#minimum)
34
44
  def minimum(scope, attr)
35
45
  scope.minimum(attr)
36
46
  end
37
47
 
48
+ # (see Adapters::Abstract#resolve)
38
49
  def resolve(scope)
39
50
  scope.to_a
40
51
  end
41
52
 
53
+ # Run this write request within an ActiveRecord transaction
54
+ # @param [Class] model_class The ActiveRecord class we are saving
55
+ # @return Result of yield
56
+ # @see Adapters::Abstract#transaction
42
57
  def transaction(model_class)
43
58
  model_class.transaction do
44
59
  yield
45
60
  end
46
61
  end
47
62
 
63
+ # (see Adapters::Abstract#sideloading_module)
48
64
  def sideloading_module
49
65
  JsonapiCompliable::Adapters::ActiveRecordSideloading
50
66
  end
51
67
 
68
+ # When a has_many relationship, we need to avoid Activerecord implicitly
69
+ # firing a query. Otherwise, simple assignment will do
70
+ # @see Adapters::Abstract#associate
52
71
  def associate(parent, child, association_name, association_type)
53
72
  if association_type == :has_many
54
73
  parent.association(association_name).loaded!
@@ -58,18 +77,21 @@ module JsonapiCompliable
58
77
  end
59
78
  end
60
79
 
80
+ # (see Adapters::Abstract#create)
61
81
  def create(model_class, create_params)
62
82
  instance = model_class.new(create_params)
63
83
  instance.save
64
84
  instance
65
85
  end
66
86
 
87
+ # (see Adapters::Abstract#update)
67
88
  def update(model_class, update_params)
68
89
  instance = model_class.find(update_params.delete(:id))
69
90
  instance.update_attributes(update_params)
70
91
  instance
71
92
  end
72
93
 
94
+ # (see Adapters::Abstract#destroy)
73
95
  def destroy(model_class, id)
74
96
  instance = model_class.find(id)
75
97
  instance.destroy