wcc-contentful 0.4.0.pre.alpha → 1.0.0.pre.rc3

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 (69) hide show
  1. checksums.yaml +5 -5
  2. data/Guardfile +43 -0
  3. data/README.md +246 -11
  4. data/Rakefile +5 -0
  5. data/app/controllers/wcc/contentful/webhook_controller.rb +25 -24
  6. data/app/jobs/wcc/contentful/webhook_enable_job.rb +36 -2
  7. data/config/routes.rb +1 -1
  8. data/doc +1 -0
  9. data/lib/tasks/download_schema.rake +12 -0
  10. data/lib/wcc/contentful.rb +70 -16
  11. data/lib/wcc/contentful/active_record_shim.rb +72 -0
  12. data/lib/wcc/contentful/configuration.rb +177 -46
  13. data/lib/wcc/contentful/content_type_indexer.rb +14 -0
  14. data/lib/wcc/contentful/downloads_schema.rb +112 -0
  15. data/lib/wcc/contentful/engine.rb +33 -14
  16. data/lib/wcc/contentful/event.rb +171 -0
  17. data/lib/wcc/contentful/events.rb +41 -0
  18. data/lib/wcc/contentful/exceptions.rb +3 -0
  19. data/lib/wcc/contentful/indexed_representation.rb +2 -2
  20. data/lib/wcc/contentful/instrumentation.rb +31 -0
  21. data/lib/wcc/contentful/link.rb +28 -0
  22. data/lib/wcc/contentful/link_visitor.rb +122 -0
  23. data/lib/wcc/contentful/middleware.rb +7 -0
  24. data/lib/wcc/contentful/middleware/store.rb +158 -0
  25. data/lib/wcc/contentful/middleware/store/caching_middleware.rb +114 -0
  26. data/lib/wcc/contentful/model.rb +37 -3
  27. data/lib/wcc/contentful/model_builder.rb +1 -0
  28. data/lib/wcc/contentful/model_methods.rb +40 -15
  29. data/lib/wcc/contentful/model_singleton_methods.rb +47 -30
  30. data/lib/wcc/contentful/rake.rb +4 -0
  31. data/lib/wcc/contentful/rspec.rb +46 -0
  32. data/lib/wcc/contentful/services.rb +61 -27
  33. data/lib/wcc/contentful/simple_client.rb +81 -25
  34. data/lib/wcc/contentful/simple_client/management.rb +43 -10
  35. data/lib/wcc/contentful/simple_client/response.rb +61 -22
  36. data/lib/wcc/contentful/simple_client/typhoeus_adapter.rb +17 -17
  37. data/lib/wcc/contentful/store.rb +7 -66
  38. data/lib/wcc/contentful/store/README.md +85 -0
  39. data/lib/wcc/contentful/store/base.rb +34 -119
  40. data/lib/wcc/contentful/store/cdn_adapter.rb +71 -12
  41. data/lib/wcc/contentful/store/factory.rb +186 -0
  42. data/lib/wcc/contentful/store/instrumentation.rb +55 -0
  43. data/lib/wcc/contentful/store/interface.rb +82 -0
  44. data/lib/wcc/contentful/store/memory_store.rb +27 -24
  45. data/lib/wcc/contentful/store/postgres_store.rb +268 -101
  46. data/lib/wcc/contentful/store/postgres_store/schema_1.sql +73 -0
  47. data/lib/wcc/contentful/store/postgres_store/schema_2.sql +21 -0
  48. data/lib/wcc/contentful/store/query.rb +246 -0
  49. data/lib/wcc/contentful/store/query/interface.rb +63 -0
  50. data/lib/wcc/contentful/store/rspec_examples.rb +48 -0
  51. data/lib/wcc/contentful/store/rspec_examples/basic_store.rb +629 -0
  52. data/lib/wcc/contentful/store/rspec_examples/include_param.rb +283 -0
  53. data/lib/wcc/contentful/store/rspec_examples/nested_queries.rb +342 -0
  54. data/lib/wcc/contentful/sync_engine.rb +181 -0
  55. data/lib/wcc/contentful/test.rb +7 -0
  56. data/lib/wcc/contentful/test/attributes.rb +56 -0
  57. data/lib/wcc/contentful/test/double.rb +76 -0
  58. data/lib/wcc/contentful/test/factory.rb +101 -0
  59. data/lib/wcc/contentful/version.rb +1 -1
  60. data/wcc-contentful.gemspec +23 -11
  61. metadata +299 -116
  62. data/Gemfile +0 -6
  63. data/app/jobs/wcc/contentful/delayed_sync_job.rb +0 -63
  64. data/lib/wcc/contentful/client_ext.rb +0 -28
  65. data/lib/wcc/contentful/graphql.rb +0 -14
  66. data/lib/wcc/contentful/graphql/builder.rb +0 -177
  67. data/lib/wcc/contentful/graphql/types.rb +0 -54
  68. data/lib/wcc/contentful/simple_client/http_adapter.rb +0 -24
  69. data/lib/wcc/contentful/store/lazy_cache_store.rb +0 -161
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wcc-contentful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.pre.alpha
4
+ version: 1.0.0.pre.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Watermark Dev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-17 00:00:00.000000000 Z
11
+ date: 2021-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: byebug
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 11.0.1
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 11.0.1
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: coveralls
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,20 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: '2.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: erb_lint
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.26
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.26
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: httplog
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +86,14 @@ dependencies:
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '10.0'
89
+ version: '13.0'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '10.0'
96
+ version: '13.0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rspec
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -80,34 +108,48 @@ dependencies:
80
108
  - - "~>"
81
109
  - !ruby/object:Gem::Version
82
110
  version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-instrumentation-matcher
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: rspec_junit_formatter
85
127
  requirement: !ruby/object:Gem::Requirement
86
128
  requirements:
87
129
  - - "~>"
88
130
  - !ruby/object:Gem::Version
89
- version: 0.3.0
131
+ version: 0.4.1
90
132
  type: :development
91
133
  prerelease: false
92
134
  version_requirements: !ruby/object:Gem::Requirement
93
135
  requirements:
94
136
  - - "~>"
95
137
  - !ruby/object:Gem::Version
96
- version: 0.3.0
138
+ version: 0.4.1
97
139
  - !ruby/object:Gem::Dependency
98
140
  name: rubocop
99
141
  requirement: !ruby/object:Gem::Requirement
100
142
  requirements:
101
- - - "~>"
143
+ - - '='
102
144
  - !ruby/object:Gem::Version
103
- version: '0.52'
145
+ version: '0.68'
104
146
  type: :development
105
147
  prerelease: false
106
148
  version_requirements: !ruby/object:Gem::Requirement
107
149
  requirements:
108
- - - "~>"
150
+ - - '='
109
151
  - !ruby/object:Gem::Version
110
- version: '0.52'
152
+ version: '0.68'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: simplecov
113
155
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +170,14 @@ dependencies:
128
170
  requirements:
129
171
  - - "~>"
130
172
  - !ruby/object:Gem::Version
131
- version: '4.0'
173
+ version: '5.0'
132
174
  type: :development
133
175
  prerelease: false
134
176
  version_requirements: !ruby/object:Gem::Requirement
135
177
  requirements:
136
178
  - - "~>"
137
179
  - !ruby/object:Gem::Version
138
- version: '4.0'
180
+ version: '5.0'
139
181
  - !ruby/object:Gem::Dependency
140
182
  name: webmock
141
183
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +192,20 @@ dependencies:
150
192
  - - "~>"
151
193
  - !ruby/object:Gem::Version
152
194
  version: '3.0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: wisper-rspec
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
153
209
  - !ruby/object:Gem::Dependency
154
210
  name: guard
155
211
  requirement: !ruby/object:Gem::Requirement
@@ -193,61 +249,47 @@ dependencies:
193
249
  - !ruby/object:Gem::Version
194
250
  version: 1.3.0
195
251
  - !ruby/object:Gem::Dependency
196
- name: generator_spec
252
+ name: guard-shell
197
253
  requirement: !ruby/object:Gem::Requirement
198
254
  requirements:
199
255
  - - "~>"
200
256
  - !ruby/object:Gem::Version
201
- version: 0.9.4
257
+ version: 0.7.1
202
258
  type: :development
203
259
  prerelease: false
204
260
  version_requirements: !ruby/object:Gem::Requirement
205
261
  requirements:
206
262
  - - "~>"
207
263
  - !ruby/object:Gem::Version
208
- version: 0.9.4
264
+ version: 0.7.1
209
265
  - !ruby/object:Gem::Dependency
210
- name: rails
266
+ name: generator_spec
211
267
  requirement: !ruby/object:Gem::Requirement
212
268
  requirements:
213
269
  - - "~>"
214
270
  - !ruby/object:Gem::Version
215
- version: '5.1'
271
+ version: 0.9.4
216
272
  type: :development
217
273
  prerelease: false
218
274
  version_requirements: !ruby/object:Gem::Requirement
219
275
  requirements:
220
276
  - - "~>"
221
277
  - !ruby/object:Gem::Version
222
- version: '5.1'
278
+ version: 0.9.4
223
279
  - !ruby/object:Gem::Dependency
224
- name: rspec-rails
280
+ name: sqlite3
225
281
  requirement: !ruby/object:Gem::Requirement
226
282
  requirements:
227
283
  - - "~>"
228
284
  - !ruby/object:Gem::Version
229
- version: '3.7'
285
+ version: 1.3.6
230
286
  type: :development
231
287
  prerelease: false
232
288
  version_requirements: !ruby/object:Gem::Requirement
233
289
  requirements:
234
290
  - - "~>"
235
291
  - !ruby/object:Gem::Version
236
- version: '3.7'
237
- - !ruby/object:Gem::Dependency
238
- name: sqlite3
239
- requirement: !ruby/object:Gem::Requirement
240
- requirements:
241
- - - ">="
242
- - !ruby/object:Gem::Version
243
- version: '0'
244
- type: :development
245
- prerelease: false
246
- version_requirements: !ruby/object:Gem::Requirement
247
- requirements:
248
- - - ">="
249
- - !ruby/object:Gem::Version
250
- version: '0'
292
+ version: 1.3.6
251
293
  - !ruby/object:Gem::Dependency
252
294
  name: timecop
253
295
  requirement: !ruby/object:Gem::Requirement
@@ -263,47 +305,33 @@ dependencies:
263
305
  - !ruby/object:Gem::Version
264
306
  version: 0.9.1
265
307
  - !ruby/object:Gem::Dependency
266
- name: contentful
267
- requirement: !ruby/object:Gem::Requirement
268
- requirements:
269
- - - '='
270
- - !ruby/object:Gem::Version
271
- version: 2.6.0
272
- type: :development
273
- prerelease: false
274
- version_requirements: !ruby/object:Gem::Requirement
275
- requirements:
276
- - - '='
277
- - !ruby/object:Gem::Version
278
- version: 2.6.0
279
- - !ruby/object:Gem::Dependency
280
- name: contentful-management
308
+ name: connection_pool
281
309
  requirement: !ruby/object:Gem::Requirement
282
310
  requirements:
283
- - - '='
311
+ - - "~>"
284
312
  - !ruby/object:Gem::Version
285
- version: 2.0.2
313
+ version: '2.2'
286
314
  type: :development
287
315
  prerelease: false
288
316
  version_requirements: !ruby/object:Gem::Requirement
289
317
  requirements:
290
- - - '='
318
+ - - "~>"
291
319
  - !ruby/object:Gem::Version
292
- version: 2.0.2
320
+ version: '2.2'
293
321
  - !ruby/object:Gem::Dependency
294
- name: graphql
322
+ name: faraday
295
323
  requirement: !ruby/object:Gem::Requirement
296
324
  requirements:
297
325
  - - "~>"
298
326
  - !ruby/object:Gem::Version
299
- version: '1.7'
327
+ version: '0.9'
300
328
  type: :development
301
329
  prerelease: false
302
330
  version_requirements: !ruby/object:Gem::Requirement
303
331
  requirements:
304
332
  - - "~>"
305
333
  - !ruby/object:Gem::Version
306
- version: '1.7'
334
+ version: '0.9'
307
335
  - !ruby/object:Gem::Dependency
308
336
  name: http
309
337
  requirement: !ruby/object:Gem::Requirement
@@ -367,33 +395,33 @@ dependencies:
367
395
  - !ruby/object:Gem::Version
368
396
  version: '5'
369
397
  - !ruby/object:Gem::Dependency
370
- name: dry-validation
398
+ name: wcc-base
371
399
  requirement: !ruby/object:Gem::Requirement
372
400
  requirements:
373
401
  - - "~>"
374
402
  - !ruby/object:Gem::Version
375
- version: 0.11.1
403
+ version: 0.3.1
376
404
  type: :runtime
377
405
  prerelease: false
378
406
  version_requirements: !ruby/object:Gem::Requirement
379
407
  requirements:
380
408
  - - "~>"
381
409
  - !ruby/object:Gem::Version
382
- version: 0.11.1
410
+ version: 0.3.1
383
411
  - !ruby/object:Gem::Dependency
384
- name: wcc-base
412
+ name: wisper
385
413
  requirement: !ruby/object:Gem::Requirement
386
414
  requirements:
387
415
  - - "~>"
388
416
  - !ruby/object:Gem::Version
389
- version: 0.3.1
417
+ version: 2.0.0
390
418
  type: :runtime
391
419
  prerelease: false
392
420
  version_requirements: !ruby/object:Gem::Requirement
393
421
  requirements:
394
422
  - - "~>"
395
423
  - !ruby/object:Gem::Version
396
- version: 0.3.1
424
+ version: 2.0.0
397
425
  description: Contentful API wrapper library exposing an ActiveRecord-like interface
398
426
  email:
399
427
  - dev@watermark.org
@@ -402,12 +430,11 @@ extensions: []
402
430
  extra_rdoc_files: []
403
431
  files:
404
432
  - ".rspec"
405
- - Gemfile
406
433
  - Guardfile
407
434
  - README.md
435
+ - Rakefile
408
436
  - app/controllers/wcc/contentful/application_controller.rb
409
437
  - app/controllers/wcc/contentful/webhook_controller.rb
410
- - app/jobs/wcc/contentful/delayed_sync_job.rb
411
438
  - app/jobs/wcc/contentful/webhook_enable_job.rb
412
439
  - bin/console
413
440
  - bin/rails
@@ -415,42 +442,68 @@ files:
415
442
  - bin/setup
416
443
  - config/initializers/mime_types.rb
417
444
  - config/routes.rb
445
+ - doc
446
+ - lib/tasks/download_schema.rake
418
447
  - lib/wcc/contentful.rb
419
- - lib/wcc/contentful/client_ext.rb
448
+ - lib/wcc/contentful/active_record_shim.rb
420
449
  - lib/wcc/contentful/configuration.rb
421
450
  - lib/wcc/contentful/content_type_indexer.rb
451
+ - lib/wcc/contentful/downloads_schema.rb
422
452
  - lib/wcc/contentful/engine.rb
453
+ - lib/wcc/contentful/event.rb
454
+ - lib/wcc/contentful/events.rb
423
455
  - lib/wcc/contentful/exceptions.rb
424
- - lib/wcc/contentful/graphql.rb
425
- - lib/wcc/contentful/graphql/builder.rb
426
- - lib/wcc/contentful/graphql/types.rb
427
456
  - lib/wcc/contentful/helpers.rb
428
457
  - lib/wcc/contentful/indexed_representation.rb
458
+ - lib/wcc/contentful/instrumentation.rb
459
+ - lib/wcc/contentful/link.rb
460
+ - lib/wcc/contentful/link_visitor.rb
461
+ - lib/wcc/contentful/middleware.rb
462
+ - lib/wcc/contentful/middleware/store.rb
463
+ - lib/wcc/contentful/middleware/store/caching_middleware.rb
429
464
  - lib/wcc/contentful/model.rb
430
465
  - lib/wcc/contentful/model_builder.rb
431
466
  - lib/wcc/contentful/model_methods.rb
432
467
  - lib/wcc/contentful/model_singleton_methods.rb
433
468
  - lib/wcc/contentful/rails.rb
469
+ - lib/wcc/contentful/rake.rb
470
+ - lib/wcc/contentful/rspec.rb
434
471
  - lib/wcc/contentful/services.rb
435
472
  - lib/wcc/contentful/simple_client.rb
436
- - lib/wcc/contentful/simple_client/http_adapter.rb
437
473
  - lib/wcc/contentful/simple_client/management.rb
438
474
  - lib/wcc/contentful/simple_client/response.rb
439
475
  - lib/wcc/contentful/simple_client/typhoeus_adapter.rb
440
476
  - lib/wcc/contentful/store.rb
477
+ - lib/wcc/contentful/store/README.md
441
478
  - lib/wcc/contentful/store/base.rb
442
479
  - lib/wcc/contentful/store/cdn_adapter.rb
443
- - lib/wcc/contentful/store/lazy_cache_store.rb
480
+ - lib/wcc/contentful/store/factory.rb
481
+ - lib/wcc/contentful/store/instrumentation.rb
482
+ - lib/wcc/contentful/store/interface.rb
444
483
  - lib/wcc/contentful/store/memory_store.rb
445
484
  - lib/wcc/contentful/store/postgres_store.rb
485
+ - lib/wcc/contentful/store/postgres_store/schema_1.sql
486
+ - lib/wcc/contentful/store/postgres_store/schema_2.sql
487
+ - lib/wcc/contentful/store/query.rb
488
+ - lib/wcc/contentful/store/query/interface.rb
489
+ - lib/wcc/contentful/store/rspec_examples.rb
490
+ - lib/wcc/contentful/store/rspec_examples/basic_store.rb
491
+ - lib/wcc/contentful/store/rspec_examples/include_param.rb
492
+ - lib/wcc/contentful/store/rspec_examples/nested_queries.rb
493
+ - lib/wcc/contentful/sync_engine.rb
446
494
  - lib/wcc/contentful/sys.rb
495
+ - lib/wcc/contentful/test.rb
496
+ - lib/wcc/contentful/test/attributes.rb
497
+ - lib/wcc/contentful/test/double.rb
498
+ - lib/wcc/contentful/test/factory.rb
447
499
  - lib/wcc/contentful/version.rb
448
500
  - wcc-contentful.gemspec
449
501
  homepage: https://github.com/watermarkchurch/wcc-contentful/wcc-contentful
450
502
  licenses:
451
503
  - MIT
452
- metadata: {}
453
- post_install_message:
504
+ metadata:
505
+ documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.0/wcc-contentful
506
+ post_install_message:
454
507
  rdoc_options: []
455
508
  require_paths:
456
509
  - lib
@@ -465,24 +518,114 @@ required_rubygems_version: !ruby/object:Gem::Requirement
465
518
  - !ruby/object:Gem::Version
466
519
  version: 1.3.1
467
520
  requirements: []
468
- rubyforge_project:
469
- rubygems_version: 2.6.11
470
- signing_key:
521
+ rubyforge_project:
522
+ rubygems_version: 2.7.6.2
523
+ signing_key:
471
524
  specification_version: 4
472
- summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://badge.fury.io/rb/wcc-contentful)
473
- [![CircleCI](https://circleci.com/gh/watermarkchurch/wcc-contentful.svg?style=svg)](https://circleci.com/gh/watermarkchurch/wcc-contentful)
525
+ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://rubygems.org/gems/wcc-contentful)
526
+ [![Build Status](https://travis-ci.org/watermarkchurch/wcc-contentful.svg?branch=master)](https://travis-ci.org/watermarkchurch/wcc-contentful)
474
527
  [![Coverage Status](https://coveralls.io/repos/github/watermarkchurch/wcc-contentful/badge.svg?branch=master)](https://coveralls.io/github/watermarkchurch/wcc-contentful?branch=master) Full
475
- documentation: https://www.rubydoc.info/github/watermarkchurch/wcc-contentful #
476
- WCC::Contentful ## Installation Add this line to your application''s Gemfile: ```ruby
477
- gem ''wcc-contentful'', require: ''wcc/contentful/rails'' ``` And then execute: $
478
- bundle Or install it yourself as: $ gem install wcc-contentful ## Configure ```ruby
479
- WCC::Contentful.configure do |config| config.access_token = <CONTENTFUL_ACCESS_TOKEN>
480
- config.space = <CONTENTFUL_SPACE_ID> end WCC::Contentful.init! ``` ## Usage ###
481
- WCC::Contentful::Model API The WCC::Contentful::Model API exposes Contentful data
482
- as a set of dynamically generated Ruby objects. These objects are based on the
483
- content types in your Contentful space. All these objects are generated by WCC::Contentful.init! The
484
- following examples show how to use this API to find entries of the `page` content
485
- type: ```ruby # Find objects by id WCC::Contentful::Model::Page.find(''1E2ucWSdacxxf233sfa3'')
528
+ documentation: https://watermarkchurch.github.io/wcc-contentful/latest/wcc-contentful/ #
529
+ WCC::Contentful An alternative to Contentful''s [contentful.rb ruby client](https://github.com/contentful/contentful.rb/),
530
+ [contentful_model](https://github.com/contentful/contentful_model), and [contentful_rails](https://github.com/contentful/contentful_rails)
531
+ gems all in one. Table of Contents: 1. [Why?](#why-did-you-rewrite-the-contentful-ruby-stack)
532
+ 2. [Installation](#installation) ## Why did you rewrite the Contentful ruby stack? We
533
+ started working with Contentful almost 3 years ago. Since that time, Contentful''s
534
+ ruby stack has improved, but there are still a number of pain points that we feel
535
+ we have addressed better with our gem. These are: * [Low-level caching](#low-level-caching)
536
+ * [Better integration with Rails & Rails models](#better-rails-integration) * [Automatic
537
+ pagination and Automatic link resolution](#automatic-pagination-and-link-resolution)
538
+ * [Automatic webhook management](#automatic-webhook-management) Our gem no longer
539
+ depends on any of the Contentful gems and interacts directly with the [Contentful
540
+ CDA](https://www.contentful.com/developers/docs/references/content-delivery-api/)
541
+ and [Content Management API](https://www.contentful.com/developers/docs/references/content-management-api/)
542
+ over HTTPS. ### Low-level caching The wcc-contentful gem enables caching at two
543
+ levels: the HTTP response using [Faraday HTTP cache middleware](https://github.com/sourcelevel/faraday-http-cache),
544
+ and at the Entry level using the Rails cache and the [Sync API](https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/synchronization)
545
+ to keep it up to date. We''ve found these two cache layers to be very effective
546
+ at reducing both round trip latency to the Content Delivery API, as well as reducing
547
+ our monthly API request usage. (which reduces our overage charges. Hooray!) ####
548
+ At the request/response level By default, the contentful.rb gem requires the [HTTP
549
+ library](https://rubygems.org/gems/http). While simple and straightforward to use,
550
+ it is not as powerful for caching. We decided to make our client conform to the
551
+ [Faraday gem''s API](https://github.com/lostisland/faraday). If you prefer not
552
+ to use Faraday, you can choose to supply your own HTTP adapter that "quacks like"
553
+ Faraday (see the [TyphoeusAdapter](https://github.com/watermarkchurch/wcc-contentful/blob/master/wcc-contentful/lib/wcc/contentful/simple_client/typhoeus_adapter.rb)
554
+ for one implementation). Using Faraday makes it easy to add Middleware. As an
555
+ example, our flagship Rails app that powers watermark.org uses the following configuration
556
+ in Production, which provides us with instrumentation through statsd, logging, and
557
+ caching: ```rb config.connection = Faraday.new do |builder| builder.use :http_cache,
558
+ shared_cache: false, store: ActiveSupport::Cache::MemoryStore.new(size: 512.megabytes),
559
+ logger: Rails.logger, serializer: Marshal, instrumenter: ActiveSupport::Notifications builder.use
560
+ :gzip builder.response :logger, Rails.logger, headers: false, bodies: false if Rails.env.development?
561
+ builder.request :instrumentation builder.adapter :typhoeus end ``` #### At the
562
+ Entry level Our stack has three layers, the middle layer being essentially a cache
563
+ for individual Entry hashes parsed out of responses from the Delivery API. We were
564
+ able to add a caching layer here which stores entries retrieved over the Sync API,
565
+ and responds to queries with cached versions of local content when possible. We
566
+ consider this to be our best innovation on the Contentful ruby stack. We have successfully
567
+ created caching layers using Memcached, Postgres, and an in-memory hash. The architecture
568
+ allows other caching implementations to be created fairly easily, and we have a
569
+ set of rspec specs that can verify that a cache store behaves appropriately. For
570
+ more information, [see the documentation on the caching modes here](https://watermarkchurch.github.io/wcc-contentful/latest/wcc-contentful/WCC/Contentful/Store.html). ###
571
+ Better Rails Integration When we initially got started with the Contentful ruby
572
+ models, we encountered one problem that was more frustrating than all others: If
573
+ a field exists in the content model, but the particular entry we''re working with
574
+ does not have that field populated, then accessing that field raised a `NoMethodError`. This
575
+ caused us to litter our code with `if defined?(entry.my_field)` which is bad practice. (Note:
576
+ this has since been fixed in contentful.rb v2). We decided it was better to not
577
+ rely on `method_missing?` (what contentful.rb does), and instead to use `define_method`
578
+ in an initializer to generate the methods for our models. This has the advantage
579
+ that calling `.instance_methods` on a model class includes all the fields present
580
+ in the content model. We also took advantage of Rails'' naming conventions to automatically
581
+ infer the content type name based on the class name. Thus in our code, we have
582
+ `app/models/page.rb` which defines `class Page << WCC::Contentful::Model::Page`,
583
+ and is automatically linked to the `page` content type ID. (Note: this is overridable
584
+ on a per-model basis) All our models are automatically generated at startup which
585
+ improves response times at the expense of initialization time. In addition, our
586
+ content model registry allows easy definition of custom models in your `app/models`
587
+ directory to override fields. This plays nice with other gems like algoliasearch-rails,
588
+ which allows you to declaratively manage your Algolia indexes. Another example
589
+ from our flagship watermark.org: ```rb class Page < WCC::Contentful::Model::Page
590
+ include AlgoliaSearch algoliasearch(index_name: ''pages'') do attribute(:title,
591
+ :slug) ... end ``` ### Automatic Pagination and Link Resolution Using the `contentful_model`
592
+ gem, calling `Page.all.load` does not give you all Page entries if there are more
593
+ than 100. To get the next page you must call `.paginate` on the response. By contrast,
594
+ `Page.find_all` in the `wcc-contentful` gem gives you a [Lazy Enumerator](https://ruby-doc.org/core-2.5.0/Enumerator/Lazy.html). As
595
+ you iterate past the 100th entry, the enumerator will automatically fetch the next
596
+ page. If you only enumerate 99 entries (say with `.take(99)`), then the second
597
+ page will never be fetched. Similarly, if your Page references an asset, say `hero_image`,
598
+ that field returns a `Link` object rather than the actual `Asset`. You must either
599
+ predefine how many links you need using `Page.load_children(3).all.load`, or detect
600
+ that `hero_image` is a `Link` like `if @page.hero_image.is_a? Contentful::Link`
601
+ and then call `.resolve` on the link. We found all of that to be too cumbersome
602
+ when we are down in a nested partial view template that may be invoked from multiple
603
+ places. The `wcc-contentful` gem, by contrast, automatically resolves a link when
604
+ accessing the associated attribute. So in our example above, `wcc-contentful` will
605
+ **always** return a `WCC::Contentful::Asset` when calling `@page.hero_image`, even
606
+ if it has to execute a query to cdn.contentful.com in order to fetch it. Warning:
607
+ This can easily lead to you exhausting your Contentful API quota if you do not carefully
608
+ tune your cache, which you should be doing anyways! The default settings will use
609
+ the Rails cache to try to cache these resolutions, but *you are ultimately responsible
610
+ for how many queries you execute!* ### Automatic webhook management The `wcc-contentful`
611
+ gem, just like `contentful_rails`, provides an Engine to be mounted in your Rails
612
+ routes file. Unlike `contentful_rails`, if you also configure `wcc-contentful`
613
+ with a Contentful Management Token and a public `app_url`, then on startup the `wcc-contentful`
614
+ engine will reach out to the Contentful Management API and ensure that a webhook
615
+ is configured to point to your app. This is one less devops burden on you, and
616
+ plays very nicely in with Heroku review apps. ## Installation Add this line to
617
+ your application''s Gemfile: ```ruby gem ''wcc-contentful'', require: ''wcc/contentful/rails''
618
+ ``` If you''re not using rails, exclude the `require:` parameter. ```ruby gem
619
+ ''wcc-contentful'' ``` And then execute: ``` $ bundle ``` Or install it yourself: ```
620
+ $ gem install wcc-contentful ``` ## Configure Put this in an initializer: ```ruby
621
+ # config/initializers/wcc_contentful.rb WCC::Contentful.configure do |config| config.access_token
622
+ = <CONTENTFUL_ACCESS_TOKEN> config.space = <CONTENTFUL_SPACE_ID> end WCC::Contentful.init!
623
+ ``` All configuration options can be found [in the rubydoc under WCC::Contentful::Configuration](https://watermarkchurch.github.io/wcc-contentful/latest/wcc-contentful/WCC/Contentful/Configuration) ##
624
+ Usage ### WCC::Contentful::Model API The WCC::Contentful::Model API exposes Contentful
625
+ data as a set of dynamically generated Ruby objects. These objects are based on
626
+ the content types in your Contentful space. All these objects are generated by
627
+ `WCC::Contentful.init!` The following examples show how to use this API to find
628
+ entries of the `page` content type: ```ruby # Find objects by id WCC::Contentful::Model::Page.find(''1E2ucWSdacxxf233sfa3'')
486
629
  # => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17
487
630
  UTC...> # Find objects by field WCC::Contentful::Model::Page.find_by(slug: ''/some-slug'')
488
631
  # => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17
@@ -522,32 +665,72 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://
522
665
  # {"sys"=> ...} # "6Fwukxxkxa6qQCC04WCaqg"=> # {"sys"=> ...} # ...} ``` The
523
666
  client handles Paging automatically within the lazy iterator returned by #items.
524
667
  This lazy iterator does not respect the `limit` param - that param is only passed
525
- through to the API to set the page size. Entries included via the `include` parameter
526
- are made available on the #includes field. This is a hash of `<entry ID> => <raw
527
- entry>` and makes it easy to grab links. This hash is added to lazily as you enumerate
528
- the pages. See the {WCC::Contentful::SimpleClient} documentation for more details. ###
529
- Accessing the APIs within application code The Model API is best exposed by defining
530
- your own model classes in the `app/models` directory which inherit from the WCC::Contentful
531
- models. ```ruby # app/models/page.rb class Page < WCC::Contentful::Model::Page #
532
- You can add additional methods here end # app/controllers/pages_controller.rb class
533
- PagesController < ApplicationController def show @page = Page.find_by(slug: params[:slug])
534
- raise Exceptions::PageNotFoundError, params[:slug] unless @page end end ``` The
535
- {WCC::Contentful::Services} singleton gives access to the other configured services.
536
- You can also include the {WCC::Contentful::ServiceAccessors} concern to define these
537
- services as attributes in a class. ```ruby class MyJob < ApplicationJob include
538
- WCC::Contentful::ServiceAccessors def perform Page.find(...) store.find(...) client.entries(...)
539
- end end ``` ## Development After checking out the repo, run `bin/setup` to install
540
- dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console`
541
- for an interactive prompt that will allow you to experiment. To install this gem
542
- onto your local machine, run `bundle exec rake install`. To release a new version,
543
- update the version number in `version.rb`, and then run `bundle exec rake release`,
544
- which will create a git tag for the version, push git commits and tags, and push
545
- the `.gem` file to [rubygems.org](https://rubygems.org). ## Contributing Bug reports
546
- and pull requests are welcome on GitHub at https://github.com/watermarkchurch/wcc-contentful.
547
- This project is intended to be a safe, welcoming space for collaboration, and contributors
548
- are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org)
549
- code of conduct. ## License The gem is available as open source under the terms
550
- of the [MIT License](http://opensource.org/licenses/MIT). ## Code of Conduct Everyone
668
+ through to the API to set the page size. If you truly want a limited subset of
669
+ response items, use [`response.items.take(n)`](https://ruby-doc.org/core-2.5.3/Enumerable.html#method-i-take) Entries
670
+ included via the `include` parameter are made available on the #includes field. This
671
+ is a hash of `<entry ID> => <raw entry>` and makes it easy to grab links. This
672
+ hash is added to lazily as you enumerate the pages. See the {WCC::Contentful::SimpleClient}
673
+ documentation for more details. ### Accessing the APIs within application code The
674
+ Model API is best exposed by defining your own model classes in the `app/models`
675
+ directory which inherit from the WCC::Contentful models. ```ruby # app/models/page.rb
676
+ class Page < WCC::Contentful::Model::Page # You can add additional methods here
677
+ end # app/controllers/pages_controller.rb class PagesController < ApplicationController
678
+ def show @page = Page.find_by(slug: params[:slug]) raise Exceptions::PageNotFoundError,
679
+ params[:slug] unless @page end end ``` The {WCC::Contentful::Services} singleton
680
+ gives access to the other configured services. You can also include the {WCC::Contentful::ServiceAccessors}
681
+ concern to define these services as attributes in a class. ```ruby class MyJob
682
+ < ApplicationJob include WCC::Contentful::ServiceAccessors def perform Page.find(...) store.find(...) client.entries(...)
683
+ end end ``` ## Architecture ![wcc-contentful diagram](./doc/wcc-contentful.png) ##
684
+ Test Helpers To use the test helpers, include the following in your rails_helper.rb: ```ruby
685
+ require ''wcc/contentful/rspec'' ``` This adds the following helpers to all your
686
+ specs: ```ruby ## # Builds a in-memory instance of the Contentful model for the
687
+ given content_type. # All attributes that are known to be required fields on the
688
+ content type # will return a default value based on the field type. instance = contentful_create(''my-content-type'',
689
+ my_field: ''some-value'') # => #<WCC::Contentful::Model::MyContentType:0x0000000005c71a78
690
+ @created_at=2018-04-16 18:41:17 UTC...> instance.my_field # => "some-value" instance.other_required_field
691
+ # => "default-value" instance.other_optional_field # => nil instance.not_a_field
692
+ # NoMethodError: undefined method `not_a_field'' for #<MyContentType:0x00007fbac81ee490> ##
693
+ # Builds a rspec double of the Contentful model for the given content_type. # All
694
+ attributes that are known to be required fields on the content type # will return
695
+ a default value based on the field type. dbl = contentful_double(''my-content-type'',
696
+ my_field: ''other-value'') # => #<Double (anonymous)> dbl.my_field # => "other-value" dbl.other_optional_field
697
+ # => nil dbl.not_a_field # => #<Double (anonymous)> received unexpected message
698
+ :not_a_field with (no args) ## # Builds out a fake Contentful entry for the given
699
+ content type, and then # stubs the Model API to return that content type for `.find`
700
+ and `.find_by` # query methods. stubbed = contentful_stub(''my-content-type'', id:
701
+ ''1234'', my_field: ''test'') WCC::Contentful::Model.find(''1234'') == stubbed
702
+ # => true MyContentType.find(''1234'') == stubbed # => true MyContentType.find_by(my_field:
703
+ ''test'') == stubbed # => true ``` ## Advanced Configuration Example Here''s an
704
+ example containing all the configuration options, and a sample setup for automatic
705
+ deployment to Heroku. This is intended to make you aware of what is possible, and
706
+ not as a general recommendation of what your setup should look like. ```ruby #
707
+ config/initializers/wcc_contentful.rb WCC::Contentful.configure do |config| config.access_token
708
+ = ENV[''CONTENTFUL_ACCESS_TOKEN''] config.space = ENV[''CONTENTFUL_SPACE_ID''] config.environment
709
+ = ENV[''CONTENTFUL_ENVIRONMENT''] config.preview_token = ENV[''CONTENTFUL_PREVIEW_ACCESS_TOKEN''] #
710
+ You may or may not want to provide this to your production server... config.management_token
711
+ = ENV[''CONTENTFUL_MANAGEMENT_TOKEN''] unless Rails.env.production? config.app_url
712
+ = "https://#{ENV[''HOSTNAME'']}" config.webhook_username = ''my-app-webhook'' config.webhook_password
713
+ = Rails.application.secrets.webhook_password config.webhook_jobs << MyOnWebhookJob config.store
714
+ = :lazy_sync, Rails.cache if Rails.env.production? # config.store = MyCustomStore.new #
715
+ Use a custom Faraday connection config.connection = Faraday.new do |builder| f.request
716
+ :retry f.request MyFaradayRequestAdapter.new ... end # OR implement some adapter
717
+ like this to use another HTTP client config.connection = MyNetHttpAdapter.new config.update_schema_file
718
+ = :never end WCC::Contentful.init! ``` For Heroku: ```yaml # Procfile web: bundle
719
+ exec rails s worker: bundle exec sidekiq release: bin/release ``` ```sh # bin/release
720
+ #!/bin/sh set -e echo "Migrating database..." bin/rake db:migrate echo "Migrating
721
+ contentful..." migrations_to_be_run=$( ... ) # somehow figure this out node_modules/.bin/contentful-migration
722
+ \ -s $CONTENTFUL_SPACE_ID -a $CONTENTFUL_MANAGEMENT_TOKEN \ -y -p "$migrations_to_be_run" echo
723
+ "Updating schema file..." rake wcc_contentful:download_schema ``` All configuration
724
+ options can be found [in the rubydoc](https://www.rubydoc.info/gems/wcc-contentful/WCC/Contentful/Configuration)
725
+ under {WCC::Contentful::Configuration} ## Development After checking out the
726
+ repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to
727
+ run the tests. You can also run `bin/console` for an interactive prompt that will
728
+ allow you to experiment. ## Contributing Bug reports and pull requests are welcome
729
+ on GitHub at https://github.com/watermarkchurch/wcc-contentful. This project is
730
+ intended to be a safe, welcoming space for collaboration, and contributors are expected
731
+ to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of
732
+ conduct. ## License The gem is available as open source under the terms of the
733
+ [MIT License](http://opensource.org/licenses/MIT). ## Code of Conduct Everyone
551
734
  interacting in the WCC::Contentful project''s codebases, issue trackers, chat rooms
552
735
  and mailing lists is expected to follow the [code of conduct](https://github.com/watermarkchurch/wcc-contentful/blob/master/CODE_OF_CONDUCT.md).'
553
736
  test_files: []