caprese 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +12 -0
  4. data/.travis.yml +18 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +41 -0
  8. data/Rakefile +8 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/caprese.gemspec +38 -0
  12. data/lib/caprese/adapter/json_api/error.rb +123 -0
  13. data/lib/caprese/adapter/json_api/json_pointer.rb +52 -0
  14. data/lib/caprese/adapter/json_api/jsonapi.rb +49 -0
  15. data/lib/caprese/adapter/json_api/link.rb +88 -0
  16. data/lib/caprese/adapter/json_api/meta.rb +37 -0
  17. data/lib/caprese/adapter/json_api/pagination_links.rb +69 -0
  18. data/lib/caprese/adapter/json_api/relationship.rb +65 -0
  19. data/lib/caprese/adapter/json_api/resource_identifier.rb +49 -0
  20. data/lib/caprese/adapter/json_api.rb +509 -0
  21. data/lib/caprese/concerns/versioning.rb +69 -0
  22. data/lib/caprese/controller/concerns/callbacks.rb +60 -0
  23. data/lib/caprese/controller/concerns/errors.rb +42 -0
  24. data/lib/caprese/controller/concerns/persistence.rb +327 -0
  25. data/lib/caprese/controller/concerns/query.rb +209 -0
  26. data/lib/caprese/controller/concerns/relationships.rb +250 -0
  27. data/lib/caprese/controller/concerns/rendering.rb +43 -0
  28. data/lib/caprese/controller/concerns/typing.rb +39 -0
  29. data/lib/caprese/controller.rb +26 -0
  30. data/lib/caprese/error.rb +121 -0
  31. data/lib/caprese/errors.rb +69 -0
  32. data/lib/caprese/record/errors.rb +82 -0
  33. data/lib/caprese/record.rb +19 -0
  34. data/lib/caprese/routing/caprese_resources.rb +27 -0
  35. data/lib/caprese/serializer/concerns/links.rb +96 -0
  36. data/lib/caprese/serializer/concerns/lookup.rb +37 -0
  37. data/lib/caprese/serializer/error_serializer.rb +13 -0
  38. data/lib/caprese/serializer.rb +13 -0
  39. data/lib/caprese/version.rb +3 -0
  40. data/lib/caprese.rb +35 -0
  41. metadata +273 -0
@@ -0,0 +1,96 @@
1
+ require 'active_support/concern'
2
+
3
+ module Caprese
4
+ class Serializer < ActiveModel::Serializer
5
+ module Links
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ # Add a links[:self] to this resource
10
+ #
11
+ # @example
12
+ # object = Order<@token='asd27h'>
13
+ # links = { self: '/api/v1/orders/asd27hß' }
14
+ link :self do
15
+ if respond_to?(url = serializer.version_name("#{object.class.name.underscore}_url"))
16
+ send(url, object.read_attribute(Caprese.config.resource_primary_key))
17
+ end
18
+ end
19
+ end
20
+
21
+ module ClassMethods
22
+ # Overridden so we can define relationship links without any code in a specific
23
+ # serializer
24
+ def has_many(name, options = {}, &block)
25
+ super name, options, &build_association_block(name)
26
+ end
27
+
28
+ # @see has_many
29
+ def has_one(name, options = {}, &block)
30
+ super name, options, &build_association_block(name)
31
+ end
32
+
33
+ # @see has_many
34
+ def belongs_to(name, options = {}, &block)
35
+ super name, options, &build_association_block(name)
36
+ end
37
+
38
+ private
39
+
40
+ # Builds a block that is passed into an association when it is defined in a specific serializer
41
+ # The block is run, and links are added to each association so when it is rendered in the
42
+ # `relationships` object of the `data` for record, it contains links to the particular association
43
+ #
44
+ # @example
45
+ # object = Order<@token=5, @product_id=10>
46
+ # reflection_name = 'product'
47
+ # # => {
48
+ # id: 'asd27h',
49
+ # type: 'orders',
50
+ # relationships: {
51
+ # product: {
52
+ # id: 'hy7sql',
53
+ # type: 'products',
54
+ # links: {
55
+ # self: '/api/v1/orders/asd27h/relationships/product',
56
+ # related: '/api/v1/orders/asd27h/product'
57
+ # }
58
+ # }
59
+ # }
60
+ # }
61
+ #
62
+ # @param [String] reflection_name the name of the relationship
63
+ # @return [Block] a block to build links for the relationship
64
+ def build_association_block(reflection_name)
65
+ primary_key = Caprese.config.resource_primary_key
66
+
67
+ Proc.new do |serializer|
68
+ link :self do
69
+ url = "relationship_definition_#{serializer.version_name("#{object.class.name.underscore}_url")}"
70
+ if respond_to? url
71
+ send(
72
+ url,
73
+ primary_key => object.read_attribute(primary_key),
74
+ relationship: reflection_name
75
+ )
76
+ end
77
+ end
78
+
79
+ link :related do
80
+ url = "relationship_data_#{serializer.version_name("#{object.class.name.underscore}_url")}"
81
+ if respond_to? url
82
+ send(
83
+ url,
84
+ primary_key => object.read_attribute(primary_key),
85
+ relationship: reflection_name
86
+ )
87
+ end
88
+ end
89
+
90
+ :nil
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,37 @@
1
+ require 'active_support/concern'
2
+
3
+ module Caprese
4
+ class Serializer < ActiveModel::Serializer
5
+ module Lookup
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ # Gets a versioned serializer for a given record
10
+ #
11
+ # @note Overrides the default since the default does not do namespaced lookup
12
+ #
13
+ # @param [ActiveRecord::Base] record the record to get a serializer for
14
+ # @param [Hash] options options for `super` to use when getting the serializer
15
+ # @return [Serializer,Nil] the serializer for the given record
16
+ def serializer_for(record, options = {})
17
+ get_serializer_for(record.class) || super
18
+ end
19
+
20
+ private
21
+
22
+ # Gets a serializer for a klass, either as the serializer explicitly defined
23
+ # for this class, or as a serializer defined for one of the klass's parents
24
+ #
25
+ # @param [Class] klass the klass to get the serializer for
26
+ # @return [Serializer] the serializer for the class
27
+ def get_serializer_for(klass)
28
+ begin
29
+ version_module("#{klass.name}Serializer").constantize
30
+ rescue NameError => e
31
+ get_serializer_for(klass.superclass) if klass.superclass
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ require 'caprese/serializer'
2
+
3
+ module Caprese
4
+ class Serializer
5
+ class ErrorSerializer < ActiveModel::Serializer::ErrorSerializer
6
+ delegate :as_json, to: :object
7
+
8
+ def resource_errors?
9
+ object.try(:record).present?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_model_serializers'
2
+ require 'caprese/concerns/versioning'
3
+ require 'caprese/serializer/concerns/links'
4
+ require 'caprese/serializer/concerns/lookup'
5
+
6
+ module Caprese
7
+ class Serializer < ActiveModel::Serializer
8
+ extend Versioning
9
+ include Versioning
10
+ include Links
11
+ include Lookup
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Caprese
2
+ VERSION = '0.2.0'
3
+ end
data/lib/caprese.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'caprese/controller'
2
+ require 'caprese/record'
3
+ require 'caprese/routing/caprese_resources'
4
+ require 'caprese/serializer'
5
+ require 'caprese/version'
6
+
7
+ module Caprese
8
+ def self.config
9
+ Controller.config
10
+ end
11
+
12
+ # Defines the primary key to use when querying records
13
+ config.resource_primary_key ||= :id
14
+
15
+ # Defines the ActiveModelSerializers adapter to use when serializing
16
+ config.adapter ||= :json_api
17
+
18
+ # Define URL options for use in UrlHelpers
19
+ config.default_url_options ||= {}
20
+
21
+ # If true, relationship data will not be serialized unless it is in `include`
22
+ config.optimize_relationships ||= true
23
+
24
+ # If true, links will be rendered as `only_path: true`
25
+ config.only_path_links ||= true
26
+
27
+ # Defines the translation scope for model and controller errors
28
+ config.i18n_scope ||= '' # 'api.v1.errors'
29
+
30
+ # The default size of any page queried
31
+ config.default_page_size ||= 10
32
+
33
+ # The maximum size of any page queried
34
+ config.max_page_size ||= 100
35
+ end
metadata ADDED
@@ -0,0 +1,273 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: caprese
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Nick Landgrebe
8
+ - Pelle ten Cate
9
+ - Kieran Klaassen
10
+ autorequire:
11
+ bindir: exe
12
+ cert_chain: []
13
+ date: 2016-09-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: active_model_serializers
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: 0.10.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: 0.10.0
29
+ - !ruby/object:Gem::Dependency
30
+ name: kaminari
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rails
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 4.2.0
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: 4.2.6
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 4.2.0
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 4.2.6
63
+ - !ruby/object:Gem::Dependency
64
+ name: bundler
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ - !ruby/object:Gem::Dependency
78
+ name: factory_girl
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ - !ruby/object:Gem::Dependency
92
+ name: coveralls
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ - !ruby/object:Gem::Dependency
106
+ name: database_cleaner
107
+ requirement: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ type: :development
113
+ prerelease: false
114
+ version_requirements: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ - !ruby/object:Gem::Dependency
120
+ name: pry-byebug
121
+ requirement: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ type: :development
127
+ prerelease: false
128
+ version_requirements: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ - !ruby/object:Gem::Dependency
134
+ name: rake
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '10.0'
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '10.0'
147
+ - !ruby/object:Gem::Dependency
148
+ name: responders
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '2.0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: '2.0'
161
+ - !ruby/object:Gem::Dependency
162
+ name: rspec
163
+ requirement: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ type: :development
169
+ prerelease: false
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ - !ruby/object:Gem::Dependency
176
+ name: rspec-rails
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ - !ruby/object:Gem::Dependency
190
+ name: sqlite3
191
+ requirement: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ type: :development
197
+ prerelease: false
198
+ version_requirements: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ description:
204
+ email:
205
+ - nick@landgre.be
206
+ executables: []
207
+ extensions: []
208
+ extra_rdoc_files: []
209
+ files:
210
+ - ".coveralls.yml"
211
+ - ".gitignore"
212
+ - ".travis.yml"
213
+ - Gemfile
214
+ - LICENSE.txt
215
+ - README.md
216
+ - Rakefile
217
+ - bin/console
218
+ - bin/setup
219
+ - caprese.gemspec
220
+ - lib/caprese.rb
221
+ - lib/caprese/adapter/json_api.rb
222
+ - lib/caprese/adapter/json_api/error.rb
223
+ - lib/caprese/adapter/json_api/json_pointer.rb
224
+ - lib/caprese/adapter/json_api/jsonapi.rb
225
+ - lib/caprese/adapter/json_api/link.rb
226
+ - lib/caprese/adapter/json_api/meta.rb
227
+ - lib/caprese/adapter/json_api/pagination_links.rb
228
+ - lib/caprese/adapter/json_api/relationship.rb
229
+ - lib/caprese/adapter/json_api/resource_identifier.rb
230
+ - lib/caprese/concerns/versioning.rb
231
+ - lib/caprese/controller.rb
232
+ - lib/caprese/controller/concerns/callbacks.rb
233
+ - lib/caprese/controller/concerns/errors.rb
234
+ - lib/caprese/controller/concerns/persistence.rb
235
+ - lib/caprese/controller/concerns/query.rb
236
+ - lib/caprese/controller/concerns/relationships.rb
237
+ - lib/caprese/controller/concerns/rendering.rb
238
+ - lib/caprese/controller/concerns/typing.rb
239
+ - lib/caprese/error.rb
240
+ - lib/caprese/errors.rb
241
+ - lib/caprese/record.rb
242
+ - lib/caprese/record/errors.rb
243
+ - lib/caprese/routing/caprese_resources.rb
244
+ - lib/caprese/serializer.rb
245
+ - lib/caprese/serializer/concerns/links.rb
246
+ - lib/caprese/serializer/concerns/lookup.rb
247
+ - lib/caprese/serializer/error_serializer.rb
248
+ - lib/caprese/version.rb
249
+ homepage: https://github.com/nicklandgrebe/caprese
250
+ licenses:
251
+ - MIT
252
+ metadata: {}
253
+ post_install_message:
254
+ rdoc_options: []
255
+ require_paths:
256
+ - lib
257
+ required_ruby_version: !ruby/object:Gem::Requirement
258
+ requirements:
259
+ - - ">="
260
+ - !ruby/object:Gem::Version
261
+ version: '2.1'
262
+ required_rubygems_version: !ruby/object:Gem::Requirement
263
+ requirements:
264
+ - - ">="
265
+ - !ruby/object:Gem::Version
266
+ version: '0'
267
+ requirements: []
268
+ rubyforge_project:
269
+ rubygems_version: 2.4.8
270
+ signing_key:
271
+ specification_version: 4
272
+ summary: Opinionated Rails library for writing RESTful APIs
273
+ test_files: []