jsonapi-resources 0.7.0 → 0.7.1.beta1
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.
- checksums.yaml +4 -4
- data/README.md +196 -190
- data/lib/generators/jsonapi/USAGE +6 -1
- data/lib/generators/jsonapi/controller_generator.rb +14 -0
- data/lib/generators/jsonapi/templates/jsonapi_controller.rb +4 -0
- data/lib/jsonapi/active_record_operations_processor.rb +4 -3
- data/lib/jsonapi/acts_as_resource_controller.rb +7 -3
- data/lib/jsonapi/error_codes.rb +26 -26
- data/lib/jsonapi/exceptions.rb +124 -53
- data/lib/jsonapi/relationship.rb +8 -0
- data/lib/jsonapi/request.rb +4 -6
- data/lib/jsonapi/resource.rb +37 -13
- data/lib/jsonapi/resource_controller.rb +14 -2
- data/lib/jsonapi/resource_serializer.rb +2 -8
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/routing_ext.rb +1 -1
- data/locales/en.yml +80 -0
- data/test/controllers/controller_test.rb +35 -5
- data/test/fixtures/active_record.rb +11 -8
- data/test/fixtures/comments.yml +1 -1
- data/test/fixtures/preferences.yml +0 -4
- data/test/lib/generators/jsonapi/controller_generator_test.rb +25 -0
- data/test/test_helper.rb +3 -0
- data/test/unit/operation/operations_processor_test.rb +3 -3
- data/test/unit/resource/resource_test.rb +20 -0
- data/test/unit/serializer/serializer_test.rb +0 -6
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb58ea800ff6a685353e48ffca57603b1db612d8
|
4
|
+
data.tar.gz: 542b9ec812a94328f50204bbbef8743d593c2413
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2ad634e949bce4a5a0f1482dbd66392e97efba3f015a3eb9c3c87b8fe0b7ed0b8bb5e1a2f6dcde3bd228ad64b51de2cd6d12aed9586980e4cadf5aeb59d6acd
|
7
|
+
data.tar.gz: 7a4a9275358f79a011b2610e316cd5190beb23e375661ef0508fb65cd3c0b08c7d0bbf751ca0ef37d98a455f842e059feb5d39be70b70b63aa2dc53308bb24ae
|
data/README.md
CHANGED
@@ -34,6 +34,7 @@ backed by ActiveRecord models or by custom objects.
|
|
34
34
|
* [Handling Exceptions] (#handling-exceptions)
|
35
35
|
* [Action Callbacks] (#action-callbacks)
|
36
36
|
* [Serializer] (#serializer)
|
37
|
+
* [Routing] (#routing)
|
37
38
|
* [Configuration] (#configuration)
|
38
39
|
* [Contributing] (#contributing)
|
39
40
|
* [License] (#license)
|
@@ -114,7 +115,7 @@ generate routes for `index`, `show` and `show_relationship`.
|
|
114
115
|
|
115
116
|
###### Immutable for Readonly
|
116
117
|
|
117
|
-
Some resources are read-only and are not to be modified through the API. Declaring a resource as immutable prevents
|
118
|
+
Some resources are read-only and are not to be modified through the API. Declaring a resource as immutable prevents
|
118
119
|
creation of routes that allow modification of the resource.
|
119
120
|
|
120
121
|
###### Immutable Heterogeneous Collections
|
@@ -187,7 +188,7 @@ end
|
|
187
188
|
##### Fetchable Attributes
|
188
189
|
|
189
190
|
By default all attributes are assumed to be fetchable. The list of fetchable attributes can be filtered by overriding
|
190
|
-
the `
|
191
|
+
the `fetchable_fields` method.
|
191
192
|
|
192
193
|
Here's an example that prevents guest users from seeing the `email` field:
|
193
194
|
|
@@ -197,7 +198,7 @@ class AuthorResource < JSONAPI::Resource
|
|
197
198
|
model_name 'Person'
|
198
199
|
has_many :posts
|
199
200
|
|
200
|
-
def
|
201
|
+
def fetchable_fields
|
201
202
|
if (context[:current_user].guest)
|
202
203
|
super - [:email]
|
203
204
|
else
|
@@ -365,7 +366,7 @@ end
|
|
365
366
|
#### Model Hints
|
366
367
|
|
367
368
|
Resource instances are created from model records. The determination of the correct resource type is performed using a
|
368
|
-
simple rule based on the model's name. The name is used to find a resource in the same module (as the originating
|
369
|
+
simple rule based on the model's name. The name is used to find a resource in the same module (as the originating
|
369
370
|
resource) that matches the name. This usually works quite well, however it can fail when model names do not match
|
370
371
|
resource names. It can also fail when using namespaced models. In this case a `model_hint` can be created to map model
|
371
372
|
names to resources. For example:
|
@@ -391,7 +392,7 @@ end
|
|
391
392
|
```
|
392
393
|
|
393
394
|
Model hints inherit from parent resources, but are not global in scope. The `model_hint` method accepts `model` and
|
394
|
-
`resource` named parameters. `model` takes an ActiveRecord class or class name (defaults to the model name), and
|
395
|
+
`resource` named parameters. `model` takes an ActiveRecord class or class name (defaults to the model name), and
|
395
396
|
`resource` takes a resource type or a resource class (defaults to the current resource's type).
|
396
397
|
|
397
398
|
#### Relationships
|
@@ -449,6 +450,7 @@ The relationship methods (`relationship`, `has_one`, and `has_many`) support the
|
|
449
450
|
* `acts_as_set` - allows the entire set of related records to be replaced in one operation. Defaults to false if not set.
|
450
451
|
* `polymorphic` - set to true to identify relationships that are polymorphic.
|
451
452
|
* `relation_name` - the name of the relation to use on the model. A lambda may be provided which allows conditional selection of the relation based on the context.
|
453
|
+
* `always_include_linkage_data` - if set to true, the relationship includes linkage data. Defaults to false if not set.
|
452
454
|
|
453
455
|
`to_one` relationships support the additional option:
|
454
456
|
* `foreign_key_on` - defaults to `:self`. To indicate that the foreign key is on the related resource specify `:related`.
|
@@ -545,8 +547,8 @@ The default value is used as if it came from the request.
|
|
545
547
|
##### Applying Filters
|
546
548
|
|
547
549
|
You may customize how a filter behaves by supplying a callable to the `:apply` option. This callable will be used to
|
548
|
-
apply that filter. The callable is passed the `records`, which is an `ActiveRecord::Relation`, the `value`, and an
|
549
|
-
`_options` hash. It is expected to return an `ActiveRecord::Relation`.
|
550
|
+
apply that filter. The callable is passed the `records`, which is an `ActiveRecord::Relation`, the `value`, and an
|
551
|
+
`_options` hash. It is expected to return an `ActiveRecord::Relation`.
|
550
552
|
|
551
553
|
This example shows how you can implement different approaches for different filters.
|
552
554
|
|
@@ -580,7 +582,7 @@ end
|
|
580
582
|
|
581
583
|
##### Verifying Filters
|
582
584
|
|
583
|
-
Because filters typically come straight from the request, it's prudent to verify their values. To do so, provide a
|
585
|
+
Because filters typically come straight from the request, it's prudent to verify their values. To do so, provide a
|
584
586
|
callable to the `verify` option. This callable will be passed the `value` and the `context`. Verify should return the
|
585
587
|
verified value, which may be modified.
|
586
588
|
|
@@ -599,7 +601,7 @@ verified value, which may be modified.
|
|
599
601
|
|
600
602
|
Basic finding by filters is supported by resources. This is implemented in the `find` and `find_by_key` finder methods.
|
601
603
|
Currently this is implemented for `ActiveRecord` based resources. The finder methods rely on the `records` method to get
|
602
|
-
an `ActiveRecord::Relation` relation. It is therefore possible to override `records` to affect the three find related
|
604
|
+
an `ActiveRecord::Relation` relation. It is therefore possible to override `records` to affect the three find related
|
603
605
|
methods.
|
604
606
|
|
605
607
|
###### Customizing base records for finder methods
|
@@ -641,7 +643,7 @@ end
|
|
641
643
|
|
642
644
|
```
|
643
645
|
|
644
|
-
For example, you may want raise an error if the user is not authorized to view the related records. See the next
|
646
|
+
For example, you may want to raise an error if the user is not authorized to view the related records. See the next
|
645
647
|
section for additional details on raising errors.
|
646
648
|
|
647
649
|
```ruby
|
@@ -730,12 +732,12 @@ like to base the sorting on variables in your context.
|
|
730
732
|
Example:
|
731
733
|
|
732
734
|
```ruby
|
733
|
-
def self.apply_sort(records, order_options, context = {})
|
735
|
+
def self.apply_sort(records, order_options, context = {})
|
734
736
|
if order_options.has?(:trending)
|
735
737
|
records = records.order_by_trending_scope
|
736
738
|
order_options - [:trending]
|
737
739
|
end
|
738
|
-
|
740
|
+
|
739
741
|
super(records, order_options, context)
|
740
742
|
end
|
741
743
|
```
|
@@ -921,7 +923,7 @@ end
|
|
921
923
|
```
|
922
924
|
|
923
925
|
The `meta` method will be called for each resource instance. Override the `meta` method on a resource class to control
|
924
|
-
the meta information for the resource. If a non empty hash is returned from `meta` this will be serialized. The `meta`
|
926
|
+
the meta information for the resource. If a non empty hash is returned from `meta` this will be serialized. The `meta`
|
925
927
|
method is called with an `options` has. The `options` hash will contain the following:
|
926
928
|
|
927
929
|
* `:serializer` -> the serializer instance
|
@@ -1041,6 +1043,10 @@ end
|
|
1041
1043
|
|
1042
1044
|
Of course you are free to extend this as needed and override action handlers or other methods.
|
1043
1045
|
|
1046
|
+
A jsonapi-controller generator is avaliable
|
1047
|
+
```
|
1048
|
+
rails generate jsonapi:controller contact
|
1049
|
+
```
|
1044
1050
|
|
1045
1051
|
###### Context
|
1046
1052
|
|
@@ -1188,31 +1194,31 @@ Error codes are provided for each error object returned, based on the error. The
|
|
1188
1194
|
|
1189
1195
|
```ruby
|
1190
1196
|
module JSONAPI
|
1191
|
-
VALIDATION_ERROR = 100
|
1192
|
-
INVALID_RESOURCE = 101
|
1193
|
-
FILTER_NOT_ALLOWED = 102
|
1194
|
-
INVALID_FIELD_VALUE = 103
|
1195
|
-
INVALID_FIELD = 104
|
1196
|
-
PARAM_NOT_ALLOWED = 105
|
1197
|
-
PARAM_MISSING = 106
|
1198
|
-
INVALID_FILTER_VALUE = 107
|
1199
|
-
COUNT_MISMATCH = 108
|
1200
|
-
KEY_ORDER_MISMATCH = 109
|
1201
|
-
KEY_NOT_INCLUDED_IN_URL = 110
|
1202
|
-
INVALID_INCLUDE = 112
|
1203
|
-
RELATION_EXISTS = 113
|
1204
|
-
INVALID_SORT_CRITERIA = 114
|
1205
|
-
INVALID_LINKS_OBJECT = 115
|
1206
|
-
TYPE_MISMATCH = 116
|
1207
|
-
INVALID_PAGE_OBJECT = 117
|
1208
|
-
INVALID_PAGE_VALUE = 118
|
1209
|
-
INVALID_FIELD_FORMAT = 119
|
1210
|
-
INVALID_FILTERS_SYNTAX = 120
|
1211
|
-
SAVE_FAILED = 121
|
1212
|
-
FORBIDDEN = 403
|
1213
|
-
RECORD_NOT_FOUND = 404
|
1214
|
-
UNSUPPORTED_MEDIA_TYPE = 415
|
1215
|
-
LOCKED = 423
|
1197
|
+
VALIDATION_ERROR = '100'
|
1198
|
+
INVALID_RESOURCE = '101'
|
1199
|
+
FILTER_NOT_ALLOWED = '102'
|
1200
|
+
INVALID_FIELD_VALUE = '103'
|
1201
|
+
INVALID_FIELD = '104'
|
1202
|
+
PARAM_NOT_ALLOWED = '105'
|
1203
|
+
PARAM_MISSING = '106'
|
1204
|
+
INVALID_FILTER_VALUE = '107'
|
1205
|
+
COUNT_MISMATCH = '108'
|
1206
|
+
KEY_ORDER_MISMATCH = '109'
|
1207
|
+
KEY_NOT_INCLUDED_IN_URL = '110'
|
1208
|
+
INVALID_INCLUDE = '112'
|
1209
|
+
RELATION_EXISTS = '113'
|
1210
|
+
INVALID_SORT_CRITERIA = '114'
|
1211
|
+
INVALID_LINKS_OBJECT = '115'
|
1212
|
+
TYPE_MISMATCH = '116'
|
1213
|
+
INVALID_PAGE_OBJECT = '117'
|
1214
|
+
INVALID_PAGE_VALUE = '118'
|
1215
|
+
INVALID_FIELD_FORMAT = '119'
|
1216
|
+
INVALID_FILTERS_SYNTAX = '120'
|
1217
|
+
SAVE_FAILED = '121'
|
1218
|
+
FORBIDDEN = '403'
|
1219
|
+
RECORD_NOT_FOUND = '404'
|
1220
|
+
UNSUPPORTED_MEDIA_TYPE = '415'
|
1221
|
+
LOCKED = '423'
|
1216
1222
|
end
|
1217
1223
|
```
|
1218
1224
|
|
@@ -1368,7 +1374,158 @@ JSONAPI::ResourceSerializer.new(PostResource, include: include_resources,
|
|
1368
1374
|
).serialize_to_hash(PostResource.new(post, nil))
|
1369
1375
|
```
|
1370
1376
|
|
1371
|
-
####
|
1377
|
+
#### Formatting
|
1378
|
+
|
1379
|
+
JR by default uses some simple rules to format (and unformat) an attribute for (de-)serialization. Strings and Integers are output to JSON
|
1380
|
+
as is, and all other values have `.to_s` applied to them. This outputs something in all cases, but it is certainly not
|
1381
|
+
correct for every situation.
|
1382
|
+
|
1383
|
+
If you want to change the way an attribute is (de-)serialized you have a couple of ways. The simplest method is to create a
|
1384
|
+
getter (and setter) method on the resource which overrides the attribute and apply the (un-)formatting there. For example:
|
1385
|
+
|
1386
|
+
```ruby
|
1387
|
+
class PersonResource < JSONAPI::Resource
|
1388
|
+
attributes :name, :email, :last_login_time
|
1389
|
+
|
1390
|
+
# Setter example
|
1391
|
+
def email=(new_email)
|
1392
|
+
@model.email = new_email.downcase
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
# Getter example
|
1396
|
+
def last_login_time
|
1397
|
+
@model.last_login_time.in_time_zone(@context[:current_user].time_zone).to_s
|
1398
|
+
end
|
1399
|
+
end
|
1400
|
+
```
|
1401
|
+
|
1402
|
+
This is simple to implement for a one off situation, but not for example if you want to apply the same formatting rules
|
1403
|
+
to all DateTime fields in your system. Another issue is the attribute on the resource will always return a formatted
|
1404
|
+
response, whether you want it or not.
|
1405
|
+
|
1406
|
+
##### Value Formatters
|
1407
|
+
|
1408
|
+
To overcome the above limitations JR uses Value Formatters. Value Formatters allow you to control the way values are
|
1409
|
+
handled for an attribute. The `format` can be set per attribute as it is declared in the resource. For example:
|
1410
|
+
|
1411
|
+
```ruby
|
1412
|
+
class PersonResource < JSONAPI::Resource
|
1413
|
+
attributes :name, :email, :spoken_languages
|
1414
|
+
attribute :last_login_time, format: :date_with_utc_timezone
|
1415
|
+
|
1416
|
+
# Getter/Setter for spoken_languages ...
|
1417
|
+
end
|
1418
|
+
```
|
1419
|
+
|
1420
|
+
A Value formatter has a `format` and an `unformat` method. Here's the base ValueFormatter and DefaultValueFormatter for
|
1421
|
+
reference:
|
1422
|
+
|
1423
|
+
```ruby
|
1424
|
+
module JSONAPI
|
1425
|
+
class ValueFormatter < Formatter
|
1426
|
+
class << self
|
1427
|
+
def format(raw_value)
|
1428
|
+
super(raw_value)
|
1429
|
+
end
|
1430
|
+
|
1431
|
+
def unformat(value)
|
1432
|
+
super(value)
|
1433
|
+
end
|
1434
|
+
...
|
1435
|
+
end
|
1436
|
+
end
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
class DefaultValueFormatter < JSONAPI::ValueFormatter
|
1440
|
+
class << self
|
1441
|
+
def format(raw_value)
|
1442
|
+
case raw_value
|
1443
|
+
when String, Integer
|
1444
|
+
return raw_value
|
1445
|
+
else
|
1446
|
+
return raw_value.to_s
|
1447
|
+
end
|
1448
|
+
end
|
1449
|
+
end
|
1450
|
+
end
|
1451
|
+
```
|
1452
|
+
|
1453
|
+
You can also create your own Value Formatter. Value Formatters must be named with the `format` name followed by
|
1454
|
+
`ValueFormatter`, i.e. `DateWithUTCTimezoneValueFormatter` and derive from `JSONAPI::ValueFormatter`. It is
|
1455
|
+
recommended that you create a directory for your formatters, called `formatters`.
|
1456
|
+
|
1457
|
+
The `format` method is called by the `ResourceSerializer` as is serializing a resource. The format method takes the
|
1458
|
+
`raw_value` parameter. `raw_value` is the value as read from the model.
|
1459
|
+
|
1460
|
+
The `unformat` method is called when processing the request. Each incoming attribute (except `links`) are run through
|
1461
|
+
the `unformat` method. The `unformat` method takes a `value`, which is the value as it comes in on the
|
1462
|
+
request. This allows you process the incoming value to alter its state before it is stored in the model.
|
1463
|
+
|
1464
|
+
###### Use a Different Default Value Formatter
|
1465
|
+
|
1466
|
+
Another way to handle formatting is to set a different default value formatter. This will affect all attributes that do
|
1467
|
+
not have a `format` set. You can do this by overriding the `default_attribute_options` method for a resource (or a base
|
1468
|
+
resource for a system wide change).
|
1469
|
+
|
1470
|
+
```ruby
|
1471
|
+
def default_attribute_options
|
1472
|
+
{format: :my_default}
|
1473
|
+
end
|
1474
|
+
```
|
1475
|
+
|
1476
|
+
and
|
1477
|
+
|
1478
|
+
```ruby
|
1479
|
+
class MyDefaultValueFormatter < JSONAPI::ValueFormatter
|
1480
|
+
class << self
|
1481
|
+
def format(raw_value)
|
1482
|
+
case raw_value
|
1483
|
+
when String, Integer
|
1484
|
+
return raw_value
|
1485
|
+
when DateTime
|
1486
|
+
return raw_value.in_time_zone('UTC').to_s
|
1487
|
+
else
|
1488
|
+
return raw_value.to_s
|
1489
|
+
end
|
1490
|
+
end
|
1491
|
+
end
|
1492
|
+
end
|
1493
|
+
```
|
1494
|
+
|
1495
|
+
This way all DateTime values will be formatted to display in the UTC timezone.
|
1496
|
+
|
1497
|
+
#### Key Format
|
1498
|
+
|
1499
|
+
By default JR uses dasherized keys as per the
|
1500
|
+
[JSON API naming recommendations](http://jsonapi.org/recommendations/#naming). This can be changed by specifying a
|
1501
|
+
different key formatter.
|
1502
|
+
|
1503
|
+
For example, to use camel cased keys with an initial lowercase character (JSON's default) create an initializer and add
|
1504
|
+
the following:
|
1505
|
+
|
1506
|
+
```ruby
|
1507
|
+
JSONAPI.configure do |config|
|
1508
|
+
# built in key format options are :underscored_key, :camelized_key and :dasherized_key
|
1509
|
+
config.json_key_format = :camelized_key
|
1510
|
+
end
|
1511
|
+
```
|
1512
|
+
|
1513
|
+
This will cause the serializer to use the `CamelizedKeyFormatter`. You can also create your own `KeyFormatter`, for
|
1514
|
+
example:
|
1515
|
+
|
1516
|
+
```ruby
|
1517
|
+
class UpperCamelizedKeyFormatter < JSONAPI::KeyFormatter
|
1518
|
+
class << self
|
1519
|
+
def format(key)
|
1520
|
+
super.camelize(:upper)
|
1521
|
+
end
|
1522
|
+
end
|
1523
|
+
end
|
1524
|
+
```
|
1525
|
+
|
1526
|
+
You would specify this in `JSONAPI.configure` as `:upper_camelized`.
|
1527
|
+
|
1528
|
+
### Routing
|
1372
1529
|
|
1373
1530
|
JR has a couple of helper methods available to assist you with setting up routes.
|
1374
1531
|
|
@@ -1535,157 +1692,6 @@ phone_number_contact GET /phone-numbers/:phone_number_id/contact(.:format) co
|
|
1535
1692
|
|
1536
1693
|
```
|
1537
1694
|
|
1538
|
-
#### Formatting
|
1539
|
-
|
1540
|
-
JR by default uses some simple rules to format (and unformat) an attribute for (de-)serialization. Strings and Integers are output to JSON
|
1541
|
-
as is, and all other values have `.to_s` applied to them. This outputs something in all cases, but it is certainly not
|
1542
|
-
correct for every situation.
|
1543
|
-
|
1544
|
-
If you want to change the way an attribute is (de-)serialized you have a couple of ways. The simplest method is to create a
|
1545
|
-
getter (and setter) method on the resource which overrides the attribute and apply the (un-)formatting there. For example:
|
1546
|
-
|
1547
|
-
```ruby
|
1548
|
-
class PersonResource < JSONAPI::Resource
|
1549
|
-
attributes :name, :email, :last_login_time
|
1550
|
-
|
1551
|
-
# Setter example
|
1552
|
-
def email=(new_email)
|
1553
|
-
@model.email = new_email.downcase
|
1554
|
-
end
|
1555
|
-
|
1556
|
-
# Getter example
|
1557
|
-
def last_login_time
|
1558
|
-
@model.last_login_time.in_time_zone(@context[:current_user].time_zone).to_s
|
1559
|
-
end
|
1560
|
-
end
|
1561
|
-
```
|
1562
|
-
|
1563
|
-
This is simple to implement for a one off situation, but not for example if you want to apply the same formatting rules
|
1564
|
-
to all DateTime fields in your system. Another issue is the attribute on the resource will always return a formatted
|
1565
|
-
response, whether you want it or not.
|
1566
|
-
|
1567
|
-
##### Value Formatters
|
1568
|
-
|
1569
|
-
To overcome the above limitations JR uses Value Formatters. Value Formatters allow you to control the way values are
|
1570
|
-
handled for an attribute. The `format` can be set per attribute as it is declared in the resource. For example:
|
1571
|
-
|
1572
|
-
```ruby
|
1573
|
-
class PersonResource < JSONAPI::Resource
|
1574
|
-
attributes :name, :email, :spoken_languages
|
1575
|
-
attribute :last_login_time, format: :date_with_utc_timezone
|
1576
|
-
|
1577
|
-
# Getter/Setter for spoken_languages ...
|
1578
|
-
end
|
1579
|
-
```
|
1580
|
-
|
1581
|
-
A Value formatter has a `format` and an `unformat` method. Here's the base ValueFormatter and DefaultValueFormatter for
|
1582
|
-
reference:
|
1583
|
-
|
1584
|
-
```ruby
|
1585
|
-
module JSONAPI
|
1586
|
-
class ValueFormatter < Formatter
|
1587
|
-
class << self
|
1588
|
-
def format(raw_value)
|
1589
|
-
super(raw_value)
|
1590
|
-
end
|
1591
|
-
|
1592
|
-
def unformat(value)
|
1593
|
-
super(value)
|
1594
|
-
end
|
1595
|
-
...
|
1596
|
-
end
|
1597
|
-
end
|
1598
|
-
end
|
1599
|
-
|
1600
|
-
class DefaultValueFormatter < JSONAPI::ValueFormatter
|
1601
|
-
class << self
|
1602
|
-
def format(raw_value)
|
1603
|
-
case raw_value
|
1604
|
-
when String, Integer
|
1605
|
-
return raw_value
|
1606
|
-
else
|
1607
|
-
return raw_value.to_s
|
1608
|
-
end
|
1609
|
-
end
|
1610
|
-
end
|
1611
|
-
end
|
1612
|
-
```
|
1613
|
-
|
1614
|
-
You can also create your own Value Formatter. Value Formatters must be named with the `format` name followed by
|
1615
|
-
`ValueFormatter`, i.e. `DateWithUTCTimezoneValueFormatter` and derive from `JSONAPI::ValueFormatter`. It is
|
1616
|
-
recommended that you create a directory for your formatters, called `formatters`.
|
1617
|
-
|
1618
|
-
The `format` method is called by the `ResourceSerializer` as is serializing a resource. The format method takes the
|
1619
|
-
`raw_value` parameter. `raw_value` is the value as read from the model.
|
1620
|
-
|
1621
|
-
The `unformat` method is called when processing the request. Each incoming attribute (except `links`) are run through
|
1622
|
-
the `unformat` method. The `unformat` method takes a `value`, which is the value as it comes in on the
|
1623
|
-
request. This allows you process the incoming value to alter its state before it is stored in the model.
|
1624
|
-
|
1625
|
-
###### Use a Different Default Value Formatter
|
1626
|
-
|
1627
|
-
Another way to handle formatting is to set a different default value formatter. This will affect all attributes that do
|
1628
|
-
not have a `format` set. You can do this by overriding the `default_attribute_options` method for a resource (or a base
|
1629
|
-
resource for a system wide change).
|
1630
|
-
|
1631
|
-
```ruby
|
1632
|
-
def default_attribute_options
|
1633
|
-
{format: :my_default}
|
1634
|
-
end
|
1635
|
-
```
|
1636
|
-
|
1637
|
-
and
|
1638
|
-
|
1639
|
-
```ruby
|
1640
|
-
class MyDefaultValueFormatter < JSONAPI::ValueFormatter
|
1641
|
-
class << self
|
1642
|
-
def format(raw_value)
|
1643
|
-
case raw_value
|
1644
|
-
when String, Integer
|
1645
|
-
return raw_value
|
1646
|
-
when DateTime
|
1647
|
-
return raw_value.in_time_zone('UTC').to_s
|
1648
|
-
else
|
1649
|
-
return raw_value.to_s
|
1650
|
-
end
|
1651
|
-
end
|
1652
|
-
end
|
1653
|
-
end
|
1654
|
-
```
|
1655
|
-
|
1656
|
-
This way all DateTime values will be formatted to display in the UTC timezone.
|
1657
|
-
|
1658
|
-
#### Key Format
|
1659
|
-
|
1660
|
-
By default JR uses dasherized keys as per the
|
1661
|
-
[JSON API naming recommendations](http://jsonapi.org/recommendations/#naming). This can be changed by specifying a
|
1662
|
-
different key formatter.
|
1663
|
-
|
1664
|
-
For example, to use camel cased keys with an initial lowercase character (JSON's default) create an initializer and add
|
1665
|
-
the following:
|
1666
|
-
|
1667
|
-
```ruby
|
1668
|
-
JSONAPI.configure do |config|
|
1669
|
-
# built in key format options are :underscored_key, :camelized_key and :dasherized_key
|
1670
|
-
config.json_key_format = :camelized_key
|
1671
|
-
end
|
1672
|
-
```
|
1673
|
-
|
1674
|
-
This will cause the serializer to use the `CamelizedKeyFormatter`. You can also create your own `KeyFormatter`, for
|
1675
|
-
example:
|
1676
|
-
|
1677
|
-
```ruby
|
1678
|
-
class UpperCamelizedKeyFormatter < JSONAPI::KeyFormatter
|
1679
|
-
class << self
|
1680
|
-
def format(key)
|
1681
|
-
super.camelize(:upper)
|
1682
|
-
end
|
1683
|
-
end
|
1684
|
-
end
|
1685
|
-
```
|
1686
|
-
|
1687
|
-
You would specify this in `JSONAPI.configure` as `:upper_camelized`.
|
1688
|
-
|
1689
1695
|
## Configuration
|
1690
1696
|
|
1691
1697
|
JR has a few configuration options. Some have already been mentioned above. To set configuration options create an
|