blueprinter-rb 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md DELETED
@@ -1,1050 +0,0 @@
1
- <img src="blueprinter_logo.svg" width="25%">
2
-
3
- # Blueprinter
4
- Blueprinter is a JSON Object Presenter for Ruby that takes business objects and breaks them down into simple hashes and serializes them to JSON. It can be used in Rails in place of other serializers (like JBuilder or ActiveModelSerializers). It is designed to be simple, direct, and performant.
5
-
6
- It heavily relies on the idea of `views` which, similar to Rails views, are ways of predefining output for data in different contexts.
7
-
8
- ## Documentation
9
- Docs can be found [here](http://www.rubydoc.info/gems/blueprinter).
10
-
11
- ## Usage
12
- <details open>
13
- <summary>Basic</summary>
14
-
15
- ---
16
-
17
- If you have an object you would like serialized, simply create a blueprint. Say, for example, you have a User record with the following attributes `[:uuid, :email, :first_name, :last_name, :password, :address]`.
18
-
19
- You may define a simple blueprint like so:
20
-
21
- ```ruby
22
- class UserBlueprint < Blueprinter::Base
23
- identifier :uuid
24
-
25
- fields :first_name, :last_name, :email
26
- end
27
- ```
28
-
29
- and then, in your code:
30
- ```ruby
31
- puts UserBlueprint.render(user) # Output is a JSON string
32
- ```
33
-
34
- And the output would look like:
35
-
36
- ```json
37
- {
38
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
39
- "email": "john.doe@some.fake.email.domain",
40
- "first_name": "John",
41
- "last_name": "Doe"
42
- }
43
- ```
44
-
45
- ---
46
- </details>
47
-
48
-
49
- <details>
50
- <summary>Collections</summary>
51
-
52
- ---
53
-
54
- You can also pass a collection object or an array to the render method.
55
-
56
- ```ruby
57
- puts UserBlueprint.render(User.all)
58
- ```
59
-
60
- This will result in JSON that looks something like this:
61
-
62
- ```json
63
- [
64
- {
65
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
66
- "email": "john.doe@some.fake.email.domain",
67
- "first_name": "John",
68
- "last_name": "Doe"
69
- },
70
- {
71
- "uuid": "733f0758-8f21-4719-875f-743af262c3ec",
72
- "email": "john.doe.2@some.fake.email.domain",
73
- "first_name": "John",
74
- "last_name": "Doe 2"
75
- }
76
- ]
77
- ```
78
-
79
- ---
80
- </details>
81
-
82
-
83
- <details>
84
- <summary>Renaming</summary>
85
-
86
- ---
87
-
88
- You can rename the resulting JSON keys in both fields and associations by using the `name` option.
89
-
90
- ```ruby
91
- class UserBlueprint < Blueprinter::Base
92
- identifier :uuid
93
-
94
- field :email, name: :login
95
-
96
- association :user_projects, name: :projects
97
- end
98
- ```
99
-
100
- This will result in JSON that looks something like this:
101
-
102
- ```json
103
- {
104
- "uuid": "92a5c732-2874-41e4-98fc-4123cd6cfa86",
105
- "login": "my@email.com",
106
- "projects": []
107
- }
108
- ```
109
-
110
- ---
111
- </details>
112
-
113
-
114
- <details>
115
- <summary>Views</summary>
116
-
117
- ---
118
-
119
- You may define different outputs by utilizing views:
120
- ```ruby
121
- class UserBlueprint < Blueprinter::Base
122
- identifier :uuid
123
- field :email, name: :login
124
-
125
- view :normal do
126
- fields :first_name, :last_name
127
- end
128
-
129
- view :extended do
130
- include_view :normal
131
- field :address
132
- association :projects
133
- end
134
- end
135
- ```
136
- A view can include fields from another view by utilizing `include_view` and `include_views`.
137
-
138
- Usage:
139
- ```ruby
140
- puts UserBlueprint.render(user, view: :extended)
141
- ```
142
-
143
- Output:
144
- ```json
145
- {
146
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
147
- "address": "123 Fake St.",
148
- "first_name": "John",
149
- "last_name": "Doe",
150
- "login": "john.doe@some.fake.email.domain"
151
- }
152
- ```
153
-
154
- ---
155
- </details>
156
-
157
-
158
- <details>
159
- <summary>Identifiers</summary>
160
-
161
- ---
162
-
163
- `identifier`s are used to specify a field or method name used as an identifier. Usually, this is something like `:id`.
164
-
165
- Example:
166
- ```rb
167
- class UserBlueprint < Blueprinter::Base
168
- identifier :uuid
169
- end
170
- ```
171
-
172
- Blueprinter `identifier`s have a few properties that set them apart from `field`s.
173
-
174
- 1. Identifiers are **always** rendered and considered their own view (the `:identifier` view).
175
- 2. When rendering, identifier fields are always sorted first, before other fields.
176
-
177
- If either of the above two developer conveniences are not desired, you can simply create your identifier fields as regular `field`s.
178
-
179
- ---
180
-
181
- </details>
182
-
183
-
184
- <details>
185
- <summary>Root</summary>
186
-
187
- ---
188
-
189
- You can also optionally pass in a root key to wrap your resulting json in:
190
- ```ruby
191
- class UserBlueprint < Blueprinter::Base
192
- identifier :uuid
193
- field :email, name: :login
194
-
195
- view :normal do
196
- fields :first_name, :last_name
197
- end
198
- end
199
- ```
200
-
201
- Usage:
202
- ```ruby
203
- puts UserBlueprint.render(user, view: :normal, root: :user)
204
- ```
205
-
206
- Output:
207
- ```json
208
- {
209
- "user": {
210
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
211
- "first_name": "John",
212
- "last_name": "Doe",
213
- "login": "john.doe@some.fake.email.domain"
214
- }
215
- }
216
- ```
217
-
218
- ---
219
- </details>
220
-
221
-
222
- <details>
223
- <summary>Meta Attributes</summary>
224
-
225
- ---
226
-
227
- You can additionally add meta-data to the json as well:
228
- ```ruby
229
- class UserBlueprint < Blueprinter::Base
230
- identifier :uuid
231
- field :email, name: :login
232
-
233
- view :normal do
234
- fields :first_name, :last_name
235
- end
236
- end
237
- ```
238
-
239
- Usage:
240
- ```ruby
241
- json = UserBlueprint.render(user, view: :normal, root: :user, meta: {links: [
242
- 'https://app.mydomain.com',
243
- 'https://alternate.mydomain.com'
244
- ]})
245
- puts json
246
- ```
247
-
248
- Output:
249
- ```json
250
- {
251
- "user": {
252
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
253
- "first_name": "John",
254
- "last_name": "Doe",
255
- "login": "john.doe@some.fake.email.domain"
256
- },
257
- "meta": {
258
- "links": [
259
- "https://app.mydomain.com",
260
- "https://alternate.mydomain.com"
261
- ]
262
- }
263
- }
264
- ```
265
- _NOTE:_ For meta attributes, a [root](#root) is mandatory.
266
-
267
- ---
268
- </details>
269
-
270
-
271
- <details>
272
- <summary>Exclude Fields</summary>
273
-
274
- ---
275
-
276
- You can specifically choose to exclude certain fields for specific views
277
- ```ruby
278
- class UserBlueprint < Blueprinter::Base
279
- identifier :uuid
280
- field :email, name: :login
281
-
282
- view :normal do
283
- fields :first_name, :last_name
284
- end
285
-
286
- view :extended do
287
- include_view :normal
288
- field :address
289
- exclude :last_name
290
- end
291
- end
292
- ```
293
-
294
- Usage:
295
- ```ruby
296
- puts UserBlueprint.render(user, view: :extended)
297
- ```
298
-
299
- Output:
300
- ```json
301
- {
302
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
303
- "address": "123 Fake St.",
304
- "first_name": "John",
305
- "login": "john.doe@some.fake.email.domain"
306
- }
307
- ```
308
-
309
- Use `excludes` to exclude multiple fields at once inline.
310
-
311
- ```ruby
312
- class UserBlueprint < Blueprinter::Base
313
- identifier :uuid
314
- field :email, name: :login
315
-
316
- view :normal do
317
- fields :age, :first_name, :last_name,
318
- end
319
-
320
- view :extended do
321
- include_view :normal
322
- field :address
323
- excludes :age, :last_name
324
- end
325
- end
326
- ```
327
-
328
- ---
329
- </details>
330
-
331
-
332
- <details>
333
- <summary>Associations</summary>
334
-
335
- ---
336
-
337
- You may include associated objects. Say for example, a user has projects:
338
- ```ruby
339
- class ProjectBlueprint < Blueprinter::Base
340
- identifier :uuid
341
- field :name
342
- end
343
-
344
- class UserBlueprint < Blueprinter::Base
345
- identifier :uuid
346
- field :email, name: :login
347
-
348
- view :normal do
349
- fields :first_name, :last_name
350
- association :projects, blueprint: ProjectBlueprint
351
- end
352
- end
353
- ```
354
-
355
- Usage:
356
- ```ruby
357
- puts UserBlueprint.render(user, view: :normal)
358
- ```
359
-
360
- Output:
361
- ```json
362
- {
363
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
364
- "first_name": "John",
365
- "last_name": "Doe",
366
- "login": "john.doe@some.fake.email.domain",
367
- "projects": [
368
- {
369
- "uuid": "dca94051-4195-42bc-a9aa-eb99f7723c82",
370
- "name": "Beach Cleanup"
371
- },
372
- {
373
- "uuid": "eb881bb5-9a51-4d27-8a29-b264c30e6160",
374
- "name": "Storefront Revamp"
375
- }
376
- ]
377
- }
378
- ```
379
-
380
- It is also possible to pass options from one Blueprint to another via an association.
381
- For example:
382
- ```ruby
383
- class VehicleBlueprint < Blueprinter::Base
384
- identifier :uuid
385
- field :full_name do |vehicle, options|
386
- "#{vehicle.model} #{options[:trim]}"
387
- end
388
- end
389
-
390
- class DriverBlueprint < Blueprinter::Base
391
- identifier :uuid
392
-
393
- view :normal do
394
- fields :first_name, :last_name
395
- association :vehicles, blueprint: VehicleBlueprint, options: { trim: 'LX' }
396
- end
397
- end
398
- ```
399
-
400
- ---
401
- </details>
402
-
403
-
404
- <details>
405
- <summary>Default Association/Field Option</summary>
406
-
407
- ---
408
-
409
- By default, an association or field that evaluates to `nil` is serialized as `nil`. A default serialized value can be specified as an option on the association or field for cases when the association/field could potentially evaluate to `nil`. You can also specify a global `field_default` or `association_default` in the Blueprinter config which will be used for all fields/associations that evaluate to nil.
410
-
411
- #### Global Config Setting
412
- ```ruby
413
- Blueprinter.configure do |config|
414
- config.field_default = "N/A"
415
- config.association_default = {}
416
- end
417
- ```
418
-
419
- #### Field-level/Association-level Setting
420
- ```ruby
421
- class UserBlueprint < Blueprinter::Base
422
- identifier :uuid
423
-
424
- view :normal do
425
- field :first_name, default: "N/A"
426
- association :company, blueprint: CompanyBlueprint, default: {}
427
- end
428
- end
429
- ```
430
-
431
- ---
432
- </details>
433
-
434
-
435
- <details>
436
- <summary>default_if</summary>
437
-
438
- ---
439
-
440
- Sometimes, you may want certain "empty" values to pass through to the default value.
441
- Blueprinter provides the ability to treat the following empty types as the default value (or `nil` if no default provided).
442
-
443
- #### Blueprinter::EMPTY_COLLECTION
444
- An empty array or empty active record collection.
445
-
446
- #### Blueprinter::EMPTY_HASH
447
- An empty hash.
448
-
449
- #### Blueprinter::EMPTY_STRING
450
- An empty string or symbol.
451
-
452
- #### Field-level/Association-level Setting
453
- ```ruby
454
- class UserBlueprint < Blueprinter::Base
455
- identifier :uuid
456
-
457
- view :normal do
458
- # If first_name is an empty string, it will become "N/A"
459
- field :first_name, default_if: Blueprinter::EmptyString, default: "N/A"
460
- # If the projects association collection is empty, it will become nil
461
- association :projects, blueprint: ProjectBlueprint, default_if: Blueprinter::EmptyCollection
462
- end
463
- end
464
- ```
465
-
466
- ---
467
- </details>
468
-
469
-
470
- <details>
471
- <summary>Supporting Dynamic Blueprints For Associations</summary>
472
-
473
- ---
474
-
475
- When defining an association, we can dynamically evaluate the blueprint. This comes in handy when adding polymorphic associations, by allowing reuse of existing blueprints.
476
- ```ruby
477
- class Task < ActiveRecord::Base
478
- belongs_to :taskable, polymorphic: true
479
- end
480
-
481
- class Project < ActiveRecord::Base
482
- has_many :tasks, as: :taskable
483
-
484
- def blueprint
485
- ProjectBlueprint
486
- end
487
- end
488
-
489
- class TaskBlueprint < Blueprinter::Base
490
- identifier :uuid
491
-
492
- view :normal do
493
- field :title, default: "N/A"
494
- association :taskable, blueprint: ->(taskable) {taskable.blueprint}, default: {}
495
- end
496
- end
497
- ```
498
- _NOTE:_ `taskable.blueprint` should return a valid Blueprint class. Currently, `has_many` is not supported because of the very nature of polymorphic associations.
499
-
500
- ---
501
- </details>
502
-
503
-
504
- <details>
505
- <summary>Defining A Field Directly In The Blueprint</summary>
506
-
507
- ---
508
-
509
- You can define a field directly in the Blueprint by passing it a block. This is especially useful if the object does not already have such an attribute or method defined, and you want to define it specifically for use with the Blueprint. This is done by passing `field` a block. The block also yields the object and any options that were passed from `render`. For example:
510
-
511
- ```ruby
512
- class UserBlueprint < Blueprinter::Base
513
- identifier :uuid
514
- field :full_name do |user, options|
515
- "#{options[:title_prefix]} #{user.first_name} #{user.last_name}"
516
- end
517
- end
518
- ```
519
-
520
- Usage:
521
-
522
- ```ruby
523
- puts UserBlueprint.render(user, title_prefix: "Mr")
524
- ```
525
-
526
- Output:
527
-
528
- ```json
529
- {
530
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
531
- "full_name": "Mr John Doe"
532
- }
533
- ```
534
-
535
- ---
536
- </details>
537
-
538
-
539
- <details>
540
- <summary>Defining An Identifier Directly In The Blueprint</summary>
541
-
542
- ---
543
-
544
- You can also pass a block to an identifier:
545
-
546
- ```ruby
547
- class UserBlueprint < Blueprinter::Base
548
- identifier :uuid do |user, options|
549
- options[:current_user].anonymize(user.uuid)
550
- end
551
- end
552
- ```
553
-
554
- Usage:
555
-
556
- ```ruby
557
- puts UserBlueprint.render(user, current_user: current_user)
558
- ```
559
-
560
- Output:
561
-
562
- ```json
563
- {
564
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
565
- }
566
- ```
567
-
568
- ---
569
- </details>
570
-
571
-
572
- <details>
573
- <summary>Defining An Association Directly In The Blueprint</summary>
574
-
575
- ---
576
-
577
- You can also pass a block to an association:
578
-
579
- ```ruby
580
- class ProjectBlueprint < Blueprinter::Base
581
- identifier :uuid
582
- field :name
583
- end
584
-
585
- class UserBlueprint < Blueprinter::Base
586
- identifier :uuid
587
-
588
- association :projects, blueprint: ProjectBlueprint do |user, options|
589
- user.projects + options[:draft_projects]
590
- end
591
- end
592
- ```
593
-
594
- Usage:
595
-
596
- ```ruby
597
- puts UserBlueprint.render(user, draft_projects: Project.where(draft: true))
598
- ```
599
-
600
- Output:
601
-
602
- ```json
603
- {
604
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
605
- "projects": [
606
- {"uuid": "b426a1e6-ac41-45ab-bfef-970b9a0b4289", "name": "query-console"},
607
- {"uuid": "5bd84d6c-4fd2-4e36-ae31-c137e39be542", "name": "blueprinter"},
608
- {"uuid": "785f5cd4-7d8d-4779-a6dd-ec5eab440eff", "name": "uncontrollable"}
609
- ]
610
- }
611
- ```
612
-
613
- ---
614
- </details>
615
-
616
-
617
- <details>
618
- <summary>Passing Additional Properties To #render</summary>
619
-
620
- ---
621
-
622
- `render` takes an options hash which you can pass additional properties, allowing you to utilize those additional properties in the `field` block. For example:
623
-
624
- ```ruby
625
- class UserBlueprint < Blueprinter::Base
626
- identifier :uuid
627
- field(:company_name) do |_user, options|
628
- options[:company].name
629
- end
630
- end
631
- ```
632
-
633
- Usage:
634
-
635
- ```ruby
636
- puts UserBlueprint.render(user, company: company)
637
- ```
638
-
639
- Output:
640
-
641
- ```json
642
- {
643
- "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
644
- "company_name": "My Company LLC"
645
- }
646
- ```
647
-
648
- ---
649
- </details>
650
-
651
-
652
- <details>
653
- <summary>Conditional Fields</summary>
654
-
655
- ---
656
-
657
- Both the `field` and the global Blueprinter Configuration supports `:if` and `:unless` options that can be used to serialize fields conditionally.
658
-
659
- #### Global Config Setting
660
- ```ruby
661
- Blueprinter.configure do |config|
662
- config.if = ->(field_name, obj, _options) { !obj[field_name].nil? }
663
- config.unless = ->(field_name, obj, _options) { obj[field_name].nil? }
664
- end
665
- ```
666
-
667
- #### Field-level Setting
668
- ```ruby
669
- class UserBlueprint < Blueprinter::Base
670
- identifier :uuid
671
- field :last_name, if: ->(_field_name, user, options) { user.first_name != options[:first_name] }
672
- field :age, unless: ->(_field_name, user, _options) { user.age < 18 }
673
- end
674
- ```
675
-
676
- _NOTE:_ The field-level setting overrides the global config setting (for the field) if both are set.
677
-
678
- ---
679
- </details>
680
-
681
-
682
- <details>
683
- <summary>Custom Formatting for Dates and Times</summary>
684
-
685
- ---
686
-
687
- To define a custom format for a Date or DateTime field, include the option `datetime_format`.
688
- This global or field-level option can be either a string representing the associated `strftime` format,
689
- or a Proc which receives the original Date/DateTime object and returns the formatted value.
690
- When using a Proc, it is the Proc's responsibility to handle any errors in formatting.
691
-
692
-
693
- #### Global Config Setting
694
- If a global datetime_format is set (either as a string format or a Proc), this option will be
695
- invoked and used to format all fields that respond to `strftime`.
696
- ```ruby
697
- Blueprinter.configure do |config|
698
- config.datetime_format = ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i }
699
- end
700
- ```
701
-
702
- #### Field-level Setting
703
- Usage (String Option):
704
- ```ruby
705
- class UserBlueprint < Blueprinter::Base
706
- identifier :name
707
- field :birthday, datetime_format: "%m/%d/%Y"
708
- end
709
- ```
710
-
711
- Output:
712
- ```json
713
- {
714
- "name": "John Doe",
715
- "birthday": "03/04/1994"
716
- }
717
- ```
718
-
719
- Usage (Proc Option):
720
- ```ruby
721
- class UserBlueprint < Blueprinter::Base
722
- identifier :name
723
- field :birthday, datetime_format: ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i }
724
- end
725
- ```
726
-
727
- Output:
728
- ```json
729
- {
730
- "name": "John Doe",
731
- "birthday": 762739200
732
- }
733
- ```
734
-
735
- _NOTE:_ The field-level setting overrides the global config setting (for the field) if both are set.
736
-
737
- ---
738
- </details>
739
-
740
-
741
- <details>
742
- <summary>Transform Classes</summary>
743
-
744
- ---
745
-
746
- Blueprinter provides the ability to specify `transform`s on views, which enable further
747
- processing and transforming of resulting view field hashes prior to serialization.
748
-
749
- Use `transform` to specify one transformer to be included for serialization.
750
- A transformer is a class, extending `Blueprinter::Transformer` and implementing the `transform` method.
751
- Whatever is returned from this `transform` method will end up being the resulting hash passed to serialization.
752
-
753
- #### Example
754
-
755
- Create a Transform class extending from `Blueprinter::Transformer`
756
- ```ruby
757
- class DynamicFieldTransformer < Blueprinter::Transformer
758
- def transform(hash, object, options)
759
- hash.merge!(object.dynamic_fields)
760
- end
761
- end
762
- ```
763
-
764
- ```ruby
765
- class User
766
- def custom_columns
767
- self.dynamic_fields #which is an array of some columns
768
- end
769
-
770
- def custom_fields
771
- custom_columns.each_with_object({}){|col,result| result[col] = self.send(col)}
772
- end
773
- end
774
- ```
775
-
776
- Then specify the transform to use for the view.
777
- ```ruby
778
- class UserBlueprint < Blueprinter::Base
779
- fields :first_name, :last_name
780
- transform DynamicTransformer
781
- end
782
- ```
783
-
784
- #### Global Transforms
785
-
786
- You can also specify global default transformers. Create one or more transformer classes extending from `Blueprinter::Transformer` and set the `default_transformers` configuration
787
- ```ruby
788
- class LowerCamelTransformer < Blueprinter::Transformer
789
- def transform(hash, _object, _options)
790
- hash.transform_keys! { |key| key.to_s.camelize(:lower).to_sym }
791
- end
792
- end
793
- ```
794
-
795
- ```ruby
796
- Blueprinter.configure do |config|
797
- config.default_transformers = [LowerCamelTransformer]
798
- end
799
- ```
800
-
801
- **Note: Any transforms specified on a per-blueprint or per-view level will override the `default_transformers` in the configuration.**
802
-
803
- ---
804
- </details>
805
-
806
- <details>
807
- <summary>Configurable Extractors</summary>
808
-
809
- ---
810
-
811
- Blueprinter gets a given objects' values from the fields definitions using extractor classes. You can substitute your own extractor class globally or per-field.
812
-
813
- #### Examples
814
-
815
- For a specific kind of field, create an extractor class extending from `Blueprinter::Extractor`
816
- ```ruby
817
- class MyFieldExtractor < Blueprinter::Extractor
818
- def extract(_field_name, _object, _local_options, _options={})
819
- # process your obscure_object
820
- _object.clarified
821
- end
822
- end
823
- ```
824
-
825
- ```ruby
826
- class MysteryBlueprint < Blueprinter::Base
827
- field :obscure_object, extractor: MyFieldExtractor
828
- end
829
- ```
830
-
831
- For a global default, create an extractor class extending from `Blueprinter::AutoExtractor` and set the `extractor_default` configuration
832
- ```ruby
833
- class MyAutoExtractor < Blueprinter::AutoExtractor
834
- def initialize
835
- super
836
- @my_field_extractor = MyFieldExtractor.new
837
- end
838
- def extractor(object, options)
839
- # dispatch to any class AutoExtractor can, plus more
840
- if detect_obscurity(object)
841
- @my_field_extractor
842
- else
843
- super
844
- end
845
- end
846
- end
847
- ```
848
-
849
- ```ruby
850
- Blueprinter.configure do |config|
851
- config.extractor_default = MyAutoExtractor
852
- end
853
- ```
854
-
855
- ---
856
- </details>
857
-
858
- <details>
859
- <summary>Sorting Fields</summary>
860
-
861
- ---
862
-
863
- By default the response sorts the keys by name. If you want the fields to be sorted in the order of definition, use the below configuration option.
864
-
865
- Usage:
866
-
867
- ```ruby
868
- Blueprinter.configure do |config|
869
- config.sort_fields_by = :definition
870
- end
871
- ```
872
-
873
- ```ruby
874
- class UserBlueprint < Blueprinter::Base
875
- identifier :name
876
- field :email
877
- field :birthday, datetime_format: "%m/%d/%Y"
878
- end
879
- ```
880
-
881
- Output:
882
- ```json
883
- {
884
- "name": "John Doe",
885
- "email": "john.doe@some.fake.email.domain",
886
- "birthday": "03/04/1994"
887
- }
888
- ```
889
-
890
- ---
891
- </details>
892
-
893
-
894
- <details>
895
- <summary>Deprecations</summary>
896
-
897
- ---
898
-
899
- When functionality in Blueprinter is invoked, that has been deprecated, the default behavior is to
900
- write a deprecation notice to stderror.
901
-
902
- However, deprecations can be configured to report at three different levels:
903
-
904
- | Key | Result |
905
- |:-----------------:|:---------------------------------------------------------------:|
906
- | `:stderr` (Default) | Deprecations will be written to stderror |
907
- | `:raise` | Deprecations will be raised as `Blueprinter::BlueprinterError`s |
908
- | `:silence` | Deprecations will be silenced and will not be raised or logged |
909
-
910
- ### Example:
911
- ```ruby
912
- Blueprinter.configure do |config|
913
- config.deprecations = :raise
914
- end
915
- ```
916
-
917
- ---
918
- </details>
919
-
920
-
921
- <details>
922
- <summary>render_as_hash</summary>
923
-
924
- ---
925
-
926
- Same as `render`, returns a Ruby Hash.
927
-
928
- Usage:
929
-
930
- ```ruby
931
- puts UserBlueprint.render_as_hash(user, company: company)
932
- ```
933
-
934
- Output:
935
-
936
- ```ruby
937
- {
938
- uuid: "733f0758-8f21-4719-875f-262c3ec743af",
939
- company_name: "My Company LLC"
940
- }
941
- ```
942
-
943
- ---
944
- </details>
945
-
946
-
947
- <details>
948
- <summary>render_as_json</summary>
949
-
950
- ---
951
-
952
- Same as `render`, returns a Ruby Hash JSONified. This will call JSONify all keys and values.
953
-
954
- Usage:
955
-
956
- ```ruby
957
- puts UserBlueprint.render_as_json(user, company: company)
958
- ```
959
-
960
- Output:
961
-
962
- ```ruby
963
- {
964
- "uuid" => "733f0758-8f21-4719-875f-262c3ec743af",
965
- "company_name" => "My Company LLC"
966
- }
967
- ```
968
-
969
- ---
970
- </details>
971
-
972
-
973
- ## Installation
974
- Add this line to your application's Gemfile:
975
-
976
- ```ruby
977
- gem 'blueprinter-rb'
978
- ```
979
-
980
- And then execute:
981
- ```bash
982
- $ bundle
983
- ```
984
-
985
- Or install it yourself as:
986
- ```bash
987
- $ gem install blueprinter
988
- ```
989
-
990
- You should also have `require 'json'` already in your project if you are not using Rails or if you are not using Oj.
991
-
992
- ## OJ
993
-
994
- By default, Blueprinter will be calling `JSON.generate(object)` internally and it expects that you have `require 'json'` already in your project's code. You may use `Oj` to generate in place of `JSON` like so:
995
-
996
- ```ruby
997
- require 'oj' # you can skip this if OJ has already been required.
998
-
999
- Blueprinter.configure do |config|
1000
- config.generator = Oj # default is JSON
1001
- end
1002
- ```
1003
-
1004
- Ensure that you have the `Oj` gem installed in your Gemfile if you haven't already:
1005
-
1006
- ```ruby
1007
- # Gemfile
1008
- gem 'oj'
1009
- ```
1010
-
1011
- ## Yajl-ruby
1012
-
1013
- [yajl-ruby](https://github.com/brianmario/yajl-ruby) is a fast and powerful JSON generator/parser. To use `yajl-ruby` in place of `JSON / OJ`, use:
1014
-
1015
- ```ruby
1016
- require 'yajl' # you can skip this if yajl has already been required.
1017
-
1018
- Blueprinter.configure do |config|
1019
- config.generator = Yajl::Encoder # default is JSON
1020
- config.method = :encode # default is generate
1021
- end
1022
- ```
1023
-
1024
- _NOTE:_ You should be doing this only if you aren't using `yajl-ruby` through the JSON API by requiring `yajl/json_gem`. More details [here](https://github.com/brianmario/yajl-ruby#json-gem-compatibility-api). In this case, `JSON.generate` is patched to use `Yajl::Encoder.encode` internally.
1025
-
1026
- ## Contributing
1027
- Feel free to browse the issues, converse, and make pull requests. If you need help, first please see if there is already an issue for your problem. Otherwise, go ahead and make a new issue.
1028
-
1029
- ### Tests
1030
- You can run tests with `bundle exec rake`.
1031
-
1032
- ### Maintain The Docs
1033
- We use Yard for documentation. Here are the following documentation rules:
1034
-
1035
- - Document all public methods we expect to be utilized by the end developers.
1036
- - Methods that are not set to private due to ruby visibility rule limitations should be marked with `@api private`.
1037
-
1038
- ## How to Document
1039
-
1040
- We use [Yard](https://yardoc.org/) for documentation. Here are the following
1041
- documentation rules:
1042
-
1043
- - Document all public methods we expect to be utilized by the end developers.
1044
- - Methods that are not set to private due to ruby visibility rule limitations should be marked with `@api private`.
1045
-
1046
- ### Releasing a New Version
1047
- To release a new version, change the version number in `version.rb`, and update the `CHANGELOG.md`. Finally, maintainers need to run `bundle exec rake release`, which will automatically create a git tag for the version, push git commits and tags to Github, and push the `.gem` file to rubygems.org.
1048
-
1049
- ## License
1050
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).