jsonapi-serializers 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ccad99bd078e37fa43bab5ffd42d9fae85414c33
4
- data.tar.gz: c4d9d97a4550a955c7d9f95c9b59e70cc60896f2
3
+ metadata.gz: b670315a342425c1d55f313aa4bc0830e1b0a69e
4
+ data.tar.gz: d2be33728c559adbee37316b70087369d5513389
5
5
  SHA512:
6
- metadata.gz: 6eb60b10f45d7892c4828b125b5a0efc139f41e1c0f737a48bcb4ffedea7162e78e5189d05e916ade934a197dec7f400b1a844c6f34bf5c1647896cee2098657
7
- data.tar.gz: f3a8ec61f5c47a1ee73760865bf7dfc6903c77d12b7aa587753ee4c4626556f3e81697455f60a9118a14002ed4978a21129e7138b86fc118d0b9e2af58aabaed
6
+ metadata.gz: 70dc34dd00b999e5805012212e80daa22510a2665b77366e657c6e809a7812ca143af7db8789fb88fe9a590f5c343bd25a164fee1903da79f74df0d52fb186d6
7
+ data.tar.gz: e254988e99b57b4108c7cecf35e065751b164722dc751fb14bdf46818f8922a3162c7780b3479625450a21d41872005411c6fbe2a6bfa56c6778a41a5f926ae0
data/README.md CHANGED
@@ -24,6 +24,7 @@ This library is up-to-date with the finalized v1 JSON API spec.
24
24
  * [Relationships](#relationships)
25
25
  * [Compound documents and includes](#compound-documents-and-includes)
26
26
  * [Relationship path handling](#relationship-path-handling)
27
+ * [Control links and data in relationships](#control-links-and-data-in-relationships)
27
28
  * [Rails example](#rails-example)
28
29
  * [Sinatra example](#sinatra-example)
29
30
  * [Unfinished business](#unfinished-business)
@@ -333,7 +334,7 @@ JSONAPI::Serializer.serialize_errors(user.errors)
333
334
 
334
335
  A more complete usage example (assumes ActiveModel):
335
336
 
336
- ```
337
+ ```ruby
337
338
  class Api::V1::ReposController < Api::V1::BaseController
338
339
  def create
339
340
  post = Post.create(post_params)
@@ -509,6 +510,52 @@ Notice a few things:
509
510
 
510
511
  The `include` param also accepts a string of [relationship paths](http://jsonapi.org/format/#fetching-includes), ie. `include: 'author,comments,comments.user'` so you can pass an `?include` query param directly through to the serialize method. Be aware that letting users pass arbitrary relationship paths might introduce security issues depending on your authorization setup, where a user could `include` a relationship they might not be authorized to see directly. Be aware of what you allow API users to include.
511
512
 
513
+ ### Control `links` and `data` in relationships
514
+
515
+ The JSON API spec allows relationships objects to contain `links`, `data`, or both.
516
+
517
+ By default, `links` are included in each relationship. You can remove links for a specific relationship by passing `include_links: false` to `has_one` or `has_many`. For example:
518
+
519
+ ```ruby
520
+ has_many :comments, include_links: false # Default is include_links: true.
521
+ ```
522
+
523
+ Notice that `links` are now excluded for the `comments` relationship:
524
+
525
+ ```json
526
+ "relationships": {
527
+ "author": {
528
+ "links": {
529
+ "self": "/posts/1/relationships/author",
530
+ "related": "/posts/1/author"
531
+ }
532
+ },
533
+ "comments": {}
534
+ }
535
+ ```
536
+
537
+ By default, `data` is excluded in each relationship. You can enable data for a specific relationship by passing `include_data: true` to `has_one` or `has_many`. For example:
538
+
539
+ ```ruby
540
+ has_one :author, include_data: true # Default is include_data: false.
541
+ ```
542
+
543
+ Notice that linkage data is now included for the `author` relationship:
544
+
545
+ ```json
546
+ "relationships": {
547
+ "author": {
548
+ "links": {
549
+ "self": "/posts/1/relationships/author",
550
+ "related": "/posts/1/author"
551
+ },
552
+ "data": {
553
+ "type": "users",
554
+ "id": "1"
555
+ }
556
+ }
557
+ ```
558
+
512
559
  ## Rails example
513
560
 
514
561
  ```ruby
@@ -52,6 +52,8 @@ module JSONAPI
52
52
  private :add_attribute
53
53
 
54
54
  def add_to_one_association(name, options = {}, &block)
55
+ options[:include_links] = options.fetch(:include_links, true)
56
+ options[:include_data] = options.fetch(:include_data, false)
55
57
  @to_one_associations ||= {}
56
58
  @to_one_associations[name] = {
57
59
  attr_or_block: block_given? ? block : name,
@@ -61,6 +63,8 @@ module JSONAPI
61
63
  private :add_to_one_association
62
64
 
63
65
  def add_to_many_association(name, options = {}, &block)
66
+ options[:include_links] = options.fetch(:include_links, true)
67
+ options[:include_data] = options.fetch(:include_data, false)
64
68
  @to_many_associations ||= {}
65
69
  @to_many_associations[name] = {
66
70
  attr_or_block: block_given? ? block : name,
@@ -97,13 +97,16 @@ module JSONAPI
97
97
  formatted_attribute_name = format_name(attribute_name)
98
98
 
99
99
  data[formatted_attribute_name] = {}
100
- links_self = relationship_self_link(attribute_name)
101
- links_related = relationship_related_link(attribute_name)
102
- data[formatted_attribute_name]['links'] = {} if links_self || links_related
103
- data[formatted_attribute_name]['links']['self'] = links_self if links_self
104
- data[formatted_attribute_name]['links']['related'] = links_related if links_related
105
100
 
106
- if @_include_linkages.include?(formatted_attribute_name)
101
+ if attr_data[:options][:include_links]
102
+ links_self = relationship_self_link(attribute_name)
103
+ links_related = relationship_related_link(attribute_name)
104
+ data[formatted_attribute_name]['links'] = {} if links_self || links_related
105
+ data[formatted_attribute_name]['links']['self'] = links_self if links_self
106
+ data[formatted_attribute_name]['links']['related'] = links_related if links_related
107
+ end
108
+
109
+ if @_include_linkages.include?(formatted_attribute_name) || attr_data[:options][:include_data]
107
110
  object = has_one_relationship(attribute_name, attr_data)
108
111
  if object.nil?
109
112
  # Spec: Resource linkage MUST be represented as one of the following:
@@ -125,17 +128,20 @@ module JSONAPI
125
128
  formatted_attribute_name = format_name(attribute_name)
126
129
 
127
130
  data[formatted_attribute_name] = {}
128
- links_self = relationship_self_link(attribute_name)
129
- links_related = relationship_related_link(attribute_name)
130
- data[formatted_attribute_name]['links'] = {} if links_self || links_related
131
- data[formatted_attribute_name]['links']['self'] = links_self if links_self
132
- data[formatted_attribute_name]['links']['related'] = links_related if links_related
131
+
132
+ if attr_data[:options][:include_links]
133
+ links_self = relationship_self_link(attribute_name)
134
+ links_related = relationship_related_link(attribute_name)
135
+ data[formatted_attribute_name]['links'] = {} if links_self || links_related
136
+ data[formatted_attribute_name]['links']['self'] = links_self if links_self
137
+ data[formatted_attribute_name]['links']['related'] = links_related if links_related
138
+ end
133
139
 
134
140
  # Spec: Resource linkage MUST be represented as one of the following:
135
141
  # - an empty array ([]) for empty to-many relationships.
136
142
  # - an array of linkage objects for non-empty to-many relationships.
137
143
  # http://jsonapi.org/format/#document-structure-resource-relationships
138
- if @_include_linkages.include?(formatted_attribute_name)
144
+ if @_include_linkages.include?(formatted_attribute_name) || attr_data[:options][:include_data]
139
145
  data[formatted_attribute_name]['data'] = []
140
146
  objects = has_many_relationship(attribute_name, attr_data) || []
141
147
  objects.each do |obj|
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Serializer
3
- VERSION = '0.10.0'
3
+ VERSION = '0.11.0'
4
4
  end
5
5
  end
@@ -352,6 +352,72 @@ describe JSONAPI::Serializer do
352
352
  },
353
353
  })
354
354
  end
355
+
356
+ it 'allows to exclude linkages for relationships' do
357
+ long_comments = create_list(:long_comment, 2)
358
+ post = create(:post, :with_author, long_comments: long_comments)
359
+ primary_data = serialize_primary(post, { serializer: MyApp::PostSerializerWithoutIncludeLinks })
360
+ expect(primary_data).to eq({
361
+ 'id' => '1',
362
+ 'type' => 'posts',
363
+ 'attributes' => {
364
+ 'title' => 'Title for Post 1'
365
+ },
366
+ 'links' => {
367
+ 'self' => '/posts/1',
368
+ },
369
+ 'relationships' => {
370
+ 'author' => {
371
+ },
372
+ 'long-comments' => {
373
+ },
374
+ }
375
+ })
376
+ end
377
+
378
+ it 'allows to include data for relationships' do
379
+ long_comments = create_list(:long_comment, 2)
380
+ post = create(:post, :with_author, long_comments: long_comments)
381
+ primary_data = serialize_primary(post, { serializer: MyApp::PostSerializerWithIncludeData })
382
+ expect(primary_data).to eq({
383
+ 'id' => '1',
384
+ 'type' => 'posts',
385
+ 'attributes' => {
386
+ 'title' => 'Title for Post 1'
387
+ },
388
+ 'links' => {
389
+ 'self' => '/posts/1',
390
+ },
391
+ 'relationships' => {
392
+ 'author' => {
393
+ 'links' => {
394
+ 'self' => '/posts/1/relationships/author',
395
+ 'related' => '/posts/1/author'
396
+ },
397
+ 'data' => {
398
+ 'type' => 'users',
399
+ 'id' => '1'
400
+ }
401
+ },
402
+ 'long-comments' => {
403
+ 'links' => {
404
+ 'self' => '/posts/1/relationships/long-comments',
405
+ 'related' => '/posts/1/long-comments'
406
+ },
407
+ 'data' => [
408
+ {
409
+ 'type' => 'long-comments',
410
+ 'id' => '1'
411
+ },
412
+ {
413
+ 'type' => 'long-comments',
414
+ 'id' => '2'
415
+ }
416
+ ]
417
+ },
418
+ }
419
+ })
420
+ end
355
421
  end
356
422
 
357
423
  # The members data and errors MUST NOT coexist in the same document.
@@ -94,7 +94,6 @@ module MyApp
94
94
 
95
95
  class PostSerializerWithMetadata
96
96
  include JSONAPI::Serializer
97
- include JSONAPI::Serializer
98
97
 
99
98
  attribute :title
100
99
  attribute :long_content do
@@ -113,6 +112,32 @@ module MyApp
113
112
  end
114
113
  end
115
114
 
115
+ class PostSerializerWithoutIncludeLinks
116
+ include JSONAPI::Serializer
117
+
118
+ attribute :title
119
+
120
+ has_one :author, include_links: false
121
+ has_many :long_comments, include_links: false
122
+
123
+ def type
124
+ :posts
125
+ end
126
+ end
127
+
128
+ class PostSerializerWithIncludeData
129
+ include JSONAPI::Serializer
130
+
131
+ attribute :title
132
+
133
+ has_one :author, include_data: true
134
+ has_many :long_comments, include_data: true
135
+
136
+ def type
137
+ :posts
138
+ end
139
+ end
140
+
116
141
  class PostSerializerWithContext < PostSerializer
117
142
  attribute :body, if: :show_body?, unless: :hide_body?
118
143
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-serializers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Fotinakis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-16 00:00:00.000000000 Z
11
+ date: 2016-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport