jsonapi-realizer 3.0.0 → 4.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 161aa73d85429aefb08d235f632784acb2275bd05516394b77053b224acbfbd0
4
- data.tar.gz: 33731346eaf5fbd9e8bdba67100208762b3848702d9a761c005bd68548384379
3
+ metadata.gz: 233431a77cbb99ea5b1fb51dc5840217f6041eb79e054e23074dbd84fa26517b
4
+ data.tar.gz: 21000506a07d24308f1f22ebb739a3b1e3863d377a1b9ae424fa8b266ff2f44e
5
5
  SHA512:
6
- metadata.gz: d2e2a566ec1566f01174e21acea1a9ebe28b6eeddb2795eb7be29b3598e41e6cfe8c9762d662cb460177a3ea4136cc86855da84ad39227b51703c30e4613e881
7
- data.tar.gz: 65c70a8803f5e66496cb807ae42571b3a3535272a8e8df7c86d087ce27256446f90ab66cc7ef869b14eff8c70c1c7dc963690a1b716dc338b31f368df7e7f1ce
6
+ metadata.gz: c8ab9db2090e5c1208c57c27a63ba5959e33aa5fc27bebfd7d5b3b452d2a16c2e0af23b50e5b5dc8fd12738adfdb39edcab3edb70318db235559cc2850b0b5d0
7
+ data.tar.gz: d2128c6ddfa8318c441b48e8beb27d785239a8737ccdd9cfa6f758b4de7981247e35680e8643dd636c0f8719fbdbd3a8cb48b243031101c89100a05abf21599d
data/README.md CHANGED
@@ -69,15 +69,13 @@ class PhotosController < ApplicationController
69
69
  def index
70
70
  realization = JSONAPI::Realizer.index(params, headers: request.headers, type: :photos)
71
71
 
72
- # See: pundit for `authorize()`
73
- authorize realization.models
74
-
75
- # See: pundit for `policy_scope()`
76
- render json: JSONAPI::Serializer.serialize(policy_scope(record), is_collection: true)
72
+ render json: JSONAPI::Serializer.serialize(realization.models, is_collection: true)
77
73
  end
78
74
  end
79
75
  ```
80
76
 
77
+ Notice that we pass `realization.model` to `ProcessPhotosService`, that's because `jsonapi-realizer` doesn't do the act of saving, creating, or destroying! We just ready up the records for you to handle (including errors).
78
+
81
79
  ### Policies
82
80
 
83
81
  Most times you will want to control what a person sees when they as for your data. We have created interfaces for this use-case and we'll show how you can use pundit (or any PORO) to constrain your in/out.
@@ -130,11 +128,16 @@ end
130
128
  ``` ruby
131
129
  class PhotosController < ApplicationController
132
130
  def index
133
- realization = JSONAPI::Realizer.index(policy(Photo).sanitize(:index, params), headers: request.headers, type: :posts)
131
+ realization = JSONAPI::Realizer.index(
132
+ policy(Photo).sanitize(:index, params),
133
+ headers: request.headers,
134
+ type: :posts,
135
+ relation: policy_scope(Photo)
136
+ )
134
137
 
135
138
  # See: pundit for `policy_scope()`
136
139
  # See: pundit for `authorize()`
137
- render json: JSONAPI::Serializer.serialize(authorize(policy_scope(realization.models)), is_collection: true)
140
+ render json: JSONAPI::Serializer.serialize(authorize(realization.models), is_collection: true)
138
141
  end
139
142
  end
140
143
  ```
@@ -152,8 +155,6 @@ An adapter must provide the following interfaces:
152
155
  0. `find_many_via`, describes how to find many models
153
156
  0. `assign_attributes_via`, describes how to write a set of properties
154
157
  0. `assign_relationships_via`, describes how to write a set of relationships
155
- 0. `create_via`, describes how to create the model
156
- 0. `update_via`, describes how to update the model
157
158
  0. `includes_via`, describes how to eager include related models
158
159
  0. `sparse_fields_via`, describes how to only return certain fields
159
160
 
@@ -173,11 +174,6 @@ class PhotoRealizer
173
174
  model.update_columns(attributes)
174
175
  end
175
176
 
176
- adapter.create_via do |model|
177
- model.save!
178
- Rails.cache.write(model.cache_key, model)
179
- end
180
-
181
177
  has_one :photographer, as: :profiles
182
178
 
183
179
  has :title
@@ -4,14 +4,11 @@ module JSONAPI
4
4
  class Create < Action
5
5
  attr_accessor :resource
6
6
 
7
- def initialize(payload:, headers:)
8
- @payload = payload
9
- @headers = headers
10
-
7
+ def initialize(payload:, headers:, scope: nil)
11
8
  raise Error::MissingContentTypeHeader unless headers.key?("Content-Type")
12
- raise Error::InvalidContentTypeHeader unless headers.fetch("Content-Type") == "application/vnd.api+json"
9
+ raise Error::InvalidContentTypeHeader unless headers.fetch("Content-Type") == JSONAPI::MEDIA_TYPE
13
10
 
14
- super(payload: payload, headers: headers)
11
+ super(payload: payload, headers: headers, scope: scope)
15
12
 
16
13
  @resource = resource_class.new(relation.new)
17
14
 
@@ -24,7 +21,6 @@ module JSONAPI
24
21
  adapter.assign_attributes_via_call(resource.model, {id: id}) if id
25
22
  adapter.assign_attributes_via_call(resource.model, attributes)
26
23
  adapter.assign_relationships_via_call(resource.model, relationships)
27
- adapter.create_via_call(resource.model)
28
24
  end
29
25
 
30
26
  def model
@@ -4,11 +4,84 @@ RSpec.describe JSONAPI::Realizer::Action::Create do
4
4
  let(:action) { described_class.new(payload: payload, headers: headers) }
5
5
 
6
6
  describe "#call" do
7
- subject { action.call }
7
+ subject { action.tap(&:call) }
8
8
 
9
- context "with no top-level data and good headers"
10
- context "with no top-level data and bad headers"
11
- context "with a good payload and bad headers"
9
+ context "with no top-level data and no content-type header no accept headers" do
10
+ let(:payload) do
11
+ {}
12
+ end
13
+ let(:headers) do
14
+ {}
15
+ end
16
+
17
+ it "raises an exception" do
18
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::MissingContentTypeHeader)
19
+ end
20
+ end
21
+
22
+ context "with no top-level data and good content-type header no accept headers" do
23
+ let(:payload) do
24
+ {}
25
+ end
26
+ let(:headers) do
27
+ {
28
+ "Content-Type" => "application/vnd.api+json",
29
+ }
30
+ end
31
+
32
+ it "raises an exception" do
33
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::MissingAcceptHeader)
34
+ end
35
+ end
36
+
37
+ context "with no top-level data and wrong content-type header" do
38
+ let(:payload) do
39
+ {}
40
+ end
41
+ let(:headers) do
42
+ {
43
+ "Content-Type" => "application/json"
44
+ }
45
+ end
46
+
47
+ it "raises an exception" do
48
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::InvalidContentTypeHeader)
49
+ end
50
+ end
51
+
52
+ context "with no top-level data and good content-type header and wrong accept header" do
53
+ let(:payload) do
54
+ {}
55
+ end
56
+ let(:headers) do
57
+ {
58
+ "Content-Type" => "application/vnd.api+json",
59
+ "Accept" => "application/json"
60
+ }
61
+ end
62
+
63
+ it "raises an exception" do
64
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::InvalidAcceptHeader)
65
+ end
66
+ end
67
+
68
+ context "with wrong top-level data and good headers" do
69
+ let(:payload) do
70
+ {
71
+ "data" => ""
72
+ }
73
+ end
74
+ let(:headers) do
75
+ {
76
+ "Content-Type" => "application/vnd.api+json",
77
+ "Accept" => "application/vnd.api+json"
78
+ }
79
+ end
80
+
81
+ it "raises an exception" do
82
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::MalformedDataRootProperty)
83
+ end
84
+ end
12
85
 
13
86
  context "with a good payload and good headers" do
14
87
  let(:payload) do
@@ -44,12 +117,6 @@ RSpec.describe JSONAPI::Realizer::Action::Create do
44
117
  expect(action.model).to be_a_kind_of(Photo)
45
118
  end
46
119
 
47
- it "assigns the id attribute" do
48
- subject
49
-
50
- expect(action.model).to have_attributes(id: "550e8400-e29b-41d4-a716-446655440000")
51
- end
52
-
53
120
  it "assigns the title attribute" do
54
121
  subject
55
122
 
@@ -68,12 +135,6 @@ RSpec.describe JSONAPI::Realizer::Action::Create do
68
135
  expect(action.model).to have_attributes(src: "http://example.com/images/productivity.png")
69
136
  end
70
137
 
71
- it "assigns the updated_at attribute" do
72
- subject
73
-
74
- expect(action.model).to have_attributes(updated_at: a_kind_of(Time))
75
- end
76
-
77
138
  it "assigns the active_photographer attribute" do
78
139
  subject
79
140
 
@@ -92,21 +153,10 @@ RSpec.describe JSONAPI::Realizer::Action::Create do
92
153
  include_examples "api"
93
154
 
94
155
  it "creates the new record" do
95
- expect {
96
- subject
97
- }.to change {
98
- Photo::STORE
99
- }.from(
100
- {}
101
- ).to(
102
- {
103
- "550e8400-e29b-41d4-a716-446655440000" => hash_including(
104
- id: "550e8400-e29b-41d4-a716-446655440000",
105
- title: "Ember Hamster",
106
- alt_text: "A hamster logo.",
107
- src: "http://example.com/images/productivity.png"
108
- )
109
- }
156
+ expect(subject.model).to have_attributes(
157
+ title: "Ember Hamster",
158
+ alt_text: "A hamster logo.",
159
+ src: "http://example.com/images/productivity.png"
110
160
  )
111
161
  end
112
162
  end
@@ -0,0 +1,27 @@
1
+ module JSONAPI
2
+ module Realizer
3
+ class Action
4
+ class Destroy < Action
5
+ attr_accessor :resource
6
+
7
+ def initialize(payload:, headers:, scope: nil, type:)
8
+ @type = type
9
+
10
+ super(payload: payload, headers: headers, scope: scope)
11
+
12
+ @resource = resource_class.new(adapter.find_via_call(relation, id))
13
+ end
14
+
15
+ def model
16
+ resource.model
17
+ end
18
+
19
+ private def id
20
+ return data.fetch("id", nil) if data
21
+
22
+ payload.fetch("id", nil)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,81 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe JSONAPI::Realizer::Action::Destroy do
4
+ let(:action) { described_class.new(payload: payload, headers: headers, type: :photos) }
5
+
6
+ describe "#model" do
7
+ subject { action.model }
8
+
9
+ context "with no top-level data and good content-type header no accept headers" do
10
+ let(:payload) do
11
+ {}
12
+ end
13
+ let(:headers) do
14
+ {
15
+ "Content-Type" => "application/vnd.api+json",
16
+ }
17
+ end
18
+
19
+ it "raises an exception" do
20
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::MissingAcceptHeader)
21
+ end
22
+ end
23
+
24
+ context "with no top-level data and good content-type header and wrong accept header" do
25
+ let(:payload) do
26
+ {}
27
+ end
28
+ let(:headers) do
29
+ {
30
+ "Content-Type" => "application/vnd.api+json",
31
+ "Accept" => "application/json"
32
+ }
33
+ end
34
+
35
+ it "raises an exception" do
36
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::InvalidAcceptHeader)
37
+ end
38
+ end
39
+
40
+ context "with a good payload and good headers" do
41
+ let(:payload) do
42
+ {
43
+ "id" => "d09ae4c6-0fc3-4c42-8fe8-6029530c3bed"
44
+ }
45
+ end
46
+ let(:headers) do
47
+ {
48
+ "Content-Type" => "application/vnd.api+json",
49
+ "Accept" => "application/vnd.api+json"
50
+ }
51
+ end
52
+
53
+ shared_examples "api" do
54
+ it "returns a photo model" do
55
+ expect(subject).to be_a_kind_of(Photo)
56
+ end
57
+
58
+ it "returns the photos attributes" do
59
+ expect(subject).to have_attributes(title: "Ember Fox", src: "http://example.com/images/productivity-2.png")
60
+ end
61
+ end
62
+
63
+ context "in a memory store", memory: true do
64
+ before do
65
+ Photo::STORE["550e8400-e29b-41d4-a716-446655440000"] = {
66
+ id: "550e8400-e29b-41d4-a716-446655440000",
67
+ title: "Ember Hamster",
68
+ src: "http://example.com/images/productivity.png"
69
+ }
70
+ Photo::STORE["d09ae4c6-0fc3-4c42-8fe8-6029530c3bed"] = {
71
+ id: "d09ae4c6-0fc3-4c42-8fe8-6029530c3bed",
72
+ title: "Ember Fox",
73
+ src: "http://example.com/images/productivity-2.png"
74
+ }
75
+ end
76
+
77
+ include_examples "api"
78
+ end
79
+ end
80
+ end
81
+ end
@@ -4,12 +4,10 @@ module JSONAPI
4
4
  class Index < Action
5
5
  attr_accessor :resources
6
6
 
7
- def initialize(payload:, headers:, type:)
8
- @payload = payload
9
- @headers = headers
7
+ def initialize(payload:, headers:, scope: nil, type:)
10
8
  @type = type
11
9
 
12
- super(payload: payload, headers: headers)
10
+ super(payload: payload, headers: headers, scope: scope)
13
11
 
14
12
  @resources = adapter.find_many_via_call(relation).map(&resource_class.method(:new))
15
13
  end
@@ -6,9 +6,36 @@ RSpec.describe JSONAPI::Realizer::Action::Index do
6
6
  describe "#models" do
7
7
  subject { action.models }
8
8
 
9
- context "with no top-level data and good headers"
10
- context "with no top-level data and bad headers"
11
- context "with a good payload and bad headers"
9
+ context "with no top-level data and good content-type header no accept headers" do
10
+ let(:payload) do
11
+ {}
12
+ end
13
+ let(:headers) do
14
+ {
15
+ "Content-Type" => "application/vnd.api+json",
16
+ }
17
+ end
18
+
19
+ it "raises an exception" do
20
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::MissingAcceptHeader)
21
+ end
22
+ end
23
+
24
+ context "with no top-level data and good content-type header and wrong accept header" do
25
+ let(:payload) do
26
+ {}
27
+ end
28
+ let(:headers) do
29
+ {
30
+ "Content-Type" => "application/vnd.api+json",
31
+ "Accept" => "application/json"
32
+ }
33
+ end
34
+
35
+ it "raises an exception" do
36
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::InvalidAcceptHeader)
37
+ end
38
+ end
12
39
 
13
40
  context "with a good payload and good headers" do
14
41
  let(:payload) do
@@ -2,15 +2,12 @@ module JSONAPI
2
2
  module Realizer
3
3
  class Action
4
4
  class Show < Action
5
-
6
5
  attr_accessor :resource
7
6
 
8
- def initialize(payload:, headers:, type:)
9
- @payload = payload
10
- @headers = headers
7
+ def initialize(payload:, headers:, scope: nil, type:)
11
8
  @type = type
12
9
 
13
- super(payload: payload, headers: headers)
10
+ super(payload: payload, headers: headers, scope: scope)
14
11
 
15
12
  @resource = resource_class.new(adapter.find_via_call(relation, id))
16
13
  end
@@ -6,9 +6,36 @@ RSpec.describe JSONAPI::Realizer::Action::Show do
6
6
  describe "#model" do
7
7
  subject { action.model }
8
8
 
9
- context "with no top-level data and good headers"
10
- context "with no top-level data and bad headers"
11
- context "with a good payload and bad headers"
9
+ context "with no top-level data and good content-type header no accept headers" do
10
+ let(:payload) do
11
+ {}
12
+ end
13
+ let(:headers) do
14
+ {
15
+ "Content-Type" => "application/vnd.api+json",
16
+ }
17
+ end
18
+
19
+ it "raises an exception" do
20
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::MissingAcceptHeader)
21
+ end
22
+ end
23
+
24
+ context "with no top-level data and good content-type header and wrong accept header" do
25
+ let(:payload) do
26
+ {}
27
+ end
28
+ let(:headers) do
29
+ {
30
+ "Content-Type" => "application/vnd.api+json",
31
+ "Accept" => "application/json"
32
+ }
33
+ end
34
+
35
+ it "raises an exception" do
36
+ expect {subject}.to raise_exception(JSONAPI::Realizer::Error::InvalidAcceptHeader)
37
+ end
38
+ end
12
39
 
13
40
  context "with a good payload and good headers" do
14
41
  let(:payload) do
@@ -4,26 +4,22 @@ module JSONAPI
4
4
  class Update < Action
5
5
  attr_accessor :resource
6
6
 
7
- def initialize(payload:, headers:)
8
- @payload = payload
9
- @headers = headers
10
-
7
+ def initialize(payload:, headers:, scope: nil)
11
8
  raise Error::MissingContentTypeHeader unless headers.key?("Content-Type")
12
- raise Error::InvalidContentTypeHeader unless headers.fetch("Content-Type") == "application/vnd.api+json"
9
+ raise Error::InvalidContentTypeHeader unless headers.fetch("Content-Type") == JSONAPI::MEDIA_TYPE
13
10
 
14
- super(payload: payload, headers: headers)
11
+ super(payload: payload, headers: headers, scope: scope)
15
12
 
16
13
  @resource = resource_class.new(adapter.find_via_call(relation, id))
17
14
 
18
- raise Error::MissingRootProperty unless payload.key?("data") || payload.key?("errors") || payload.key?("meta")
19
- raise Error::MissingTypeResourceProperty if payload.key?("data") && data.kind_of?(Hash) && !data.key?("type")
20
- raise Error::MissingTypeResourceProperty if payload.key?("data") && data.kind_of?(Array) && !data.all? {|resource| resource.key?("type")}
15
+ raise Error::MissingRootProperty unless @payload.key?("data") || @payload.key?("errors") || @payload.key?("meta")
16
+ raise Error::MissingTypeResourceProperty if @payload.key?("data") && data.kind_of?(Hash) && !data.key?("type")
17
+ raise Error::MissingTypeResourceProperty if @payload.key?("data") && data.kind_of?(Array) && !data.all? {|resource| resource.key?("type")}
21
18
  end
22
19
 
23
20
  def call
24
21
  adapter.assign_attributes_via_call(resource.model, attributes)
25
22
  adapter.assign_relationships_via_call(resource.model, relationships)
26
- adapter.update_via_call(resource.model)
27
23
  end
28
24
 
29
25
  def model
@@ -4,7 +4,7 @@ RSpec.describe JSONAPI::Realizer::Action::Update do
4
4
  let(:action) { described_class.new(payload: payload, headers: headers) }
5
5
 
6
6
  describe "#call" do
7
- subject { action.call }
7
+ subject { action.tap(&:call) }
8
8
 
9
9
  context "with no top-level data and no content-type header no accept headers" do
10
10
  let(:payload) do
@@ -134,12 +134,6 @@ RSpec.describe JSONAPI::Realizer::Action::Update do
134
134
  expect(action.model).to have_attributes(src: "http://example.com/images/productivity-2.png")
135
135
  end
136
136
 
137
- it "assigns the updated_at attribute" do
138
- subject
139
-
140
- expect(action.model).to have_attributes(updated_at: a_kind_of(Time))
141
- end
142
-
143
137
  it "assigns the active_photographer attribute" do
144
138
  subject
145
139
 
@@ -163,27 +157,11 @@ RSpec.describe JSONAPI::Realizer::Action::Update do
163
157
  include_examples "api"
164
158
 
165
159
  it "updates the record" do
166
- expect {
167
- subject
168
- }.to change {
169
- Photo::STORE
170
- }.from(
171
- {
172
- "550e8400-e29b-41d4-a716-446655440000" => hash_including(
173
- id: "550e8400-e29b-41d4-a716-446655440000",
174
- title: "Ember Hamster",
175
- src: "http://example.com/images/productivity.png"
176
- )
177
- }
178
- ).to(
179
- {
180
- "550e8400-e29b-41d4-a716-446655440000" => hash_including(
181
- id: "550e8400-e29b-41d4-a716-446655440000",
182
- title: "Ember Hamster 2",
183
- alt_text: "A hamster logo.",
184
- src: "http://example.com/images/productivity-2.png"
185
- )
186
- }
160
+ expect(subject.model).to have_attributes(
161
+ id: "550e8400-e29b-41d4-a716-446655440000",
162
+ title: "Ember Hamster 2",
163
+ alt_text: "A hamster logo.",
164
+ src: "http://example.com/images/productivity-2.png"
187
165
  )
188
166
  end
189
167
  end
@@ -5,62 +5,66 @@ module JSONAPI
5
5
  require_relative "action/update"
6
6
  require_relative "action/show"
7
7
  require_relative "action/index"
8
+ require_relative "action/destroy"
8
9
 
9
10
  attr_reader :payload
10
11
  attr_reader :headers
11
12
 
12
- def initialize(payload:, headers:)
13
- raise Error::MissingAcceptHeader unless headers.key?("Accept")
14
- raise Error::InvalidAcceptHeader unless headers.fetch("Accept") == "application/vnd.api+json"
15
- raise Error::TooManyRootProperties if payload.key?("data") && payload.key?("errors")
16
- raise Error::IncludeWithoutDataProperty if payload.key?("include") && !payload.key?("data")
17
- raise Error::MalformedDataRootProperty unless payload.key?("data") && data.kind_of?(Array) || data.kind_of?(Hash) || data.nil?
13
+ def initialize(payload:, headers:, scope: nil)
14
+ @scope = scope
15
+ @headers = headers
16
+ @payload = payload
17
+
18
+ raise Error::MissingAcceptHeader unless @headers.key?("Accept")
19
+ raise Error::InvalidAcceptHeader unless @headers.fetch("Accept") == JSONAPI::MEDIA_TYPE
20
+ raise Error::IncludeWithoutDataProperty if @payload.key?("include") && !@payload.key?("data")
21
+ raise Error::MalformedDataRootProperty if @payload.key?("data") && !(data.kind_of?(Array) || data.kind_of?(Hash) || data.nil?)
18
22
  end
19
23
 
20
24
  def call; end
21
25
 
22
26
  private def model_class
23
- resource_class.model_class
27
+ resource_class.model_class if resource_class
24
28
  end
25
29
 
26
30
  private def resource_class
27
- configuration.resource_class
31
+ configuration.resource_class if configuration
28
32
  end
29
33
 
30
34
  private def adapter
31
- configuration.adapter
35
+ configuration.adapter if configuration
32
36
  end
33
37
 
34
- private def relation_after_inclusion(relation)
38
+ private def relation_after_inclusion(subrelation)
35
39
  if includes.any?
36
- resource_class.include_via_call(relation, includes)
40
+ resource_class.include_via_call(subrelation, includes)
37
41
  else
38
- relation
42
+ subrelation
39
43
  end
40
44
  end
41
45
 
42
- private def relation_after_fields(relation)
46
+ private def relation_after_fields(subrelation)
43
47
  if fields.any?
44
- resource_class.sparse_fields_call(relation, fields)
48
+ resource_class.sparse_fields_call(subrelation, fields)
45
49
  else
46
- relation
50
+ subrelation
47
51
  end
48
52
  end
49
53
 
50
54
  private def relation
51
55
  relation_after_fields(
52
56
  relation_after_inclusion(
53
- model_class
57
+ @scope || model_class
54
58
  )
55
59
  )
56
60
  end
57
61
 
58
62
  private def data
59
- payload.fetch("data")
63
+ payload.fetch("data", nil)
60
64
  end
61
65
 
62
66
  private def type
63
- data["type"].to_s.dasherize if data
67
+ (@type || data["type"]).to_s.dasherize if @type || data
64
68
  end
65
69
 
66
70
  private def attributes
@@ -88,6 +92,7 @@ module JSONAPI
88
92
  end
89
93
 
90
94
  def includes
95
+ return [] unless payload.present?
91
96
  return [] unless payload.key?("include")
92
97
 
93
98
  payload.
@@ -111,6 +116,7 @@ module JSONAPI
111
116
  end
112
117
 
113
118
  def fields
119
+ return [] unless payload.present?
114
120
  return [] unless payload.key?("fields")
115
121
 
116
122
  payload.
@@ -138,7 +144,7 @@ module JSONAPI
138
144
  end
139
145
 
140
146
  private def configuration
141
- JSONAPI::Realizer.type_mapping.fetch(type)
147
+ JSONAPI::Realizer.type_mapping.fetch(type) if type
142
148
  end
143
149
  end
144
150
  end
@@ -1,13 +1,13 @@
1
1
  require "spec_helper"
2
2
 
3
3
  RSpec.describe JSONAPI::Realizer::Action do
4
+ let(:headers) do
5
+ {
6
+ "Accept" => JSONAPI::MEDIA_TYPE
7
+ }
8
+ end
4
9
  let(:action) do
5
- Class.new(described_class) do
6
- def initialize(payload:, type:)
7
- @payload = payload
8
- @type = type
9
- end
10
- end.new(payload: payload, type: :photos)
10
+ ExampleAction.new(payload: payload, headers: headers, type: :photos)
11
11
  end
12
12
 
13
13
  describe "#includes" do
@@ -16,6 +16,7 @@ RSpec.describe JSONAPI::Realizer::Action do
16
16
  context "with a two good and one bad" do
17
17
  let(:payload) do
18
18
  {
19
+ "data" => nil,
19
20
  "include" => "active_photographer,active_photographer.posts.comments,active_photographer.posts"
20
21
  }
21
22
  end
@@ -32,6 +33,7 @@ RSpec.describe JSONAPI::Realizer::Action do
32
33
  context "with a two good and one bad" do
33
34
  let(:payload) do
34
35
  {
36
+ "data" => nil,
35
37
  "fields" => "title,active_photographer.posts.comments.body,active_photographer.name"
36
38
  }
37
39
  end
@@ -31,14 +31,6 @@ module JSONAPI
31
31
  end
32
32
  end)))
33
33
  end
34
-
35
- create_via do |model|
36
- model.create!
37
- end
38
-
39
- update_via do |model|
40
- model.update!
41
- end
42
34
  end
43
35
  end
44
36
  end
@@ -25,21 +25,6 @@ module JSONAPI
25
25
  include_via do |model_class, includes|
26
26
  model_class
27
27
  end
28
-
29
- create_via do |model|
30
- model.assign_attributes(id: model.id || SecureRandom.uuid)
31
- model.assign_attributes(updated_at: Time.now)
32
- model.class.const_get("STORE")[model.id] = model.class.const_get("ATTRIBUTES").inject({}) do |hash, key|
33
- hash.merge({ key => model.public_send(key) })
34
- end
35
- end
36
-
37
- update_via do |model|
38
- model.assign_attributes(updated_at: Time.now)
39
- model.class.const_get("STORE")[model.id] = model.class.const_get("ATTRIBUTES").inject({}) do |hash, key|
40
- hash.merge({ key => model.public_send(key) })
41
- end
42
- end
43
28
  end
44
29
  end
45
30
  end
@@ -20,8 +20,6 @@ module JSONAPI
20
20
  raise ArgumentError, "need to provide a Adapter.find_many_via_call interface" unless instance_variable_defined?(:@find_many_via_call)
21
21
  raise ArgumentError, "need to provide a Adapter.assign_attributes_via interface" unless instance_variable_defined?(:@assign_attributes_via_call)
22
22
  raise ArgumentError, "need to provide a Adapter.assign_relationships_via interface" unless instance_variable_defined?(:@assign_relationships_via_call)
23
- raise ArgumentError, "need to provide a Adapter.create_via interface" unless instance_variable_defined?(:@create_via_call)
24
- raise ArgumentError, "need to provide a Adapter.update_via interface" unless instance_variable_defined?(:@update_via_call)
25
23
  raise ArgumentError, "need to provide a Adapter.sparse_fields interface" unless instance_variable_defined?(:@sparse_fields_call)
26
24
  raise ArgumentError, "need to provide a Adapter.include_via interface" unless instance_variable_defined?(:@include_via_call)
27
25
  end
@@ -34,14 +32,6 @@ module JSONAPI
34
32
  @find_many_via_call = callback
35
33
  end
36
34
 
37
- def create_via(&callback)
38
- @create_via_call = callback
39
- end
40
-
41
- def update_via(&callback)
42
- @update_via_call = callback
43
- end
44
-
45
35
  def assign_attributes_via(&callback)
46
36
  @assign_attributes_via_call = callback
47
37
  end
@@ -66,14 +56,6 @@ module JSONAPI
66
56
  @find_many_via_call.call(model_class)
67
57
  end
68
58
 
69
- def create_via_call(model)
70
- @create_via_call.call(model)
71
- end
72
-
73
- def update_via_call(model)
74
- @update_via_call.call(model)
75
- end
76
-
77
59
  def assign_attributes_via_call(model, attributes)
78
60
  @assign_attributes_via_call.call(model, attributes)
79
61
  end
@@ -26,13 +26,5 @@ RSpec.describe JSONAPI::Realizer::Adapter do
26
26
  context "when the assign_attributes_via interface isn't defined" do
27
27
 
28
28
  end
29
-
30
- context "when the create_via interface isn't defined" do
31
-
32
- end
33
-
34
- context "when the update_via interface isn't defined" do
35
-
36
- end
37
29
  end
38
30
  end
@@ -9,7 +9,6 @@ module JSONAPI
9
9
  require_relative "error/missing_content_type_header"
10
10
  require_relative "error/missing_root_property"
11
11
  require_relative "error/missing_type_resource_property"
12
- require_relative "error/too_many_root_properties"
13
12
  end
14
13
  end
15
14
  end
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Realizer
3
- VERSION = "3.0.0"
3
+ VERSION = "4.0.0"
4
4
  end
5
5
  end
@@ -4,6 +4,8 @@ require "active_support/core_ext/enumerable"
4
4
  require "active_support/core_ext/string"
5
5
 
6
6
  module JSONAPI
7
+ MEDIA_TYPE = "application/vnd.api+json"
8
+
7
9
  module Realizer
8
10
  require_relative "realizer/version"
9
11
  require_relative "realizer/error"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi-realizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kurtis Rainbolt-Greene
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-24 00:00:00.000000000 Z
11
+ date: 2018-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -136,6 +136,8 @@ files:
136
136
  - lib/jsonapi/realizer/action.rb
137
137
  - lib/jsonapi/realizer/action/create.rb
138
138
  - lib/jsonapi/realizer/action/create_spec.rb
139
+ - lib/jsonapi/realizer/action/destroy.rb
140
+ - lib/jsonapi/realizer/action/destroy_spec.rb
139
141
  - lib/jsonapi/realizer/action/index.rb
140
142
  - lib/jsonapi/realizer/action/index_spec.rb
141
143
  - lib/jsonapi/realizer/action/show.rb
@@ -156,7 +158,6 @@ files:
156
158
  - lib/jsonapi/realizer/error/missing_content_type_header.rb
157
159
  - lib/jsonapi/realizer/error/missing_root_property.rb
158
160
  - lib/jsonapi/realizer/error/missing_type_resource_property.rb
159
- - lib/jsonapi/realizer/error/too_many_root_properties.rb
160
161
  - lib/jsonapi/realizer/resource.rb
161
162
  - lib/jsonapi/realizer/version.rb
162
163
  - lib/jsonapi/realizer/version_spec.rb
@@ -181,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
182
  version: '0'
182
183
  requirements: []
183
184
  rubyforge_project:
184
- rubygems_version: 2.7.4
185
+ rubygems_version: 2.7.6
185
186
  signing_key:
186
187
  specification_version: 4
187
188
  summary: A way to take json:api requests and turn them into models
@@ -1,9 +0,0 @@
1
- module JSONAPI
2
- module Realizer
3
- class Error
4
- class TooManyRootProperties < Error
5
-
6
- end
7
- end
8
- end
9
- end