graphiti 1.0.alpha.19 → 1.0.alpha.20

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
  SHA1:
3
- metadata.gz: 87db44b8b56a2b6341dd62b0d1ef7bdf37703127
4
- data.tar.gz: 934774ad413a6ac695b612253249620efc0f7c9b
3
+ metadata.gz: 3e748663dcd4e93cbaaf9304a1d5690863f0ff5d
4
+ data.tar.gz: 056c6acfc9aa1c68509a8e650b8dc0da393262d3
5
5
  SHA512:
6
- metadata.gz: 51ca1feec8cc701fd3786449d747f5ea44f72fd4e533fcb598793f74dc550e87aaa39a53eb4144e623653503a690a25d9ce2bf84b1bae253a66d92e5d84ab2fb
7
- data.tar.gz: bf9acf3ecc4b5be6db1bc9d3e46c3591b59d48391bfa941fedf3c525418e8a8d393d91fee4ba9745e25a2fda1d92fb4499f500be323a55524a8c5cee2e72b9d8
6
+ metadata.gz: 4a80207f722f242e74182f7b2029739cd13db051554ccf09dfc97815f1c8c1d17a89f0b7f2e945f75e4be4461c4cc1c4bbde3afbe392d4059087110b1def1678
7
+ data.tar.gz: 5001801f9b0f0ed74f127f6efce115e307b79dc18a08fa9a662a3a1b7b8b3602b8d7b6bb2d620f9b14f7ec271ee70dd19160fe7ce775f4836289a0ae3ce9b775
@@ -26,6 +26,10 @@ module Graphiti
26
26
  app_controller_code
27
27
  end
28
28
 
29
+ inject_into_file 'config/application.rb', after: "Rails::Application\n" do
30
+ " routes.default_url_options[:host] = ENV.fetch('HOST', 'http://localhost:3000')\n"
31
+ end
32
+
29
33
  insert_into_file "config/routes.rb", :after => "Rails.application.routes.draw do\n" do
30
34
  <<-STR
31
35
  scope path: ApplicationResource.endpoint_namespace, defaults: { format: :jsonapi } do
@@ -10,5 +10,6 @@ class ApplicationResource < Graphiti::Resource
10
10
  <%- end -%>
11
11
  self.abstract_class = true
12
12
  self.adapter = Graphiti::Adapters::ActiveRecord
13
+ self.base_url = Rails.application.routes.default_url_options[:host]
13
14
  self.endpoint_namespace = '<%= api_namespace %>'
14
15
  end
@@ -23,7 +23,6 @@ RSpec.describe "<%= type %>#create", type: :request do
23
23
  make_request
24
24
  }.to change { <%= model_class %>.count }.by(1)
25
25
  <%= var %> = <%= model_class %>.last
26
- # assert on properties
27
26
  expect(response.status).to eq(201)
28
27
  end
29
28
  end
@@ -15,7 +15,7 @@ RSpec.describe "<%= type %>#index", type: :request do
15
15
  expect(<%= resource_class %>).to receive(:all).and_call_original
16
16
  make_request
17
17
  expect(response.status).to eq(200)
18
- expect(d.map(&:jsonapi_type).uniq).to eq(['<%= type %>'])
18
+ expect(d.map(&:jsonapi_type).uniq).to match_array(['<%= type %>'])
19
19
  expect(d.map(&:id)).to match_array([<%= var %>1.id, <%= var %>2.id])
20
20
  end
21
21
  end
@@ -27,8 +27,6 @@ RSpec.describe "<%= type %>#update", type: :request do
27
27
  make_request
28
28
  }.to change { <%= var %>.reload.attributes }
29
29
  expect(response.status).to eq(200)
30
-
31
- # ... assert updates attributes ...
32
30
  end
33
31
  end
34
32
  end
@@ -258,12 +258,28 @@ Only one resource can be associated to a given url/verb combination.
258
258
  end
259
259
 
260
260
  class PolymorphicResourceChildNotFound < Base
261
- def initialize(resource_class, model)
261
+ def initialize(resource_class, type: nil, model: nil)
262
262
  @resource_class = resource_class
263
263
  @model = model
264
+ @type = type
264
265
  end
265
266
 
266
267
  def message
268
+ @model ? model_message : type_message
269
+ end
270
+
271
+ def model_message
272
+ <<-MSG
273
+ #{@resource_class}: Tried to find Resource subclass with model #{@model.class}, but nothing found!
274
+
275
+ Make sure all your child classes are assigned and associated to the right models:
276
+
277
+ # One of these should be assocated to model #{@model.class}:
278
+ self.polymorphic = ['Subclass1Resource', 'Subclass2Resource']
279
+ MSG
280
+ end
281
+
282
+ def type_message
267
283
  <<-MSG
268
284
  #{@resource_class}: Tried to find Resource subclass with model #{@model.class}, but nothing found!
269
285
 
@@ -474,13 +490,13 @@ Consider using a named relationship instead, e.g. 'has_one :top_comment'
474
490
  end
475
491
 
476
492
  class InvalidInclude < Base
477
- def initialize(resource_class, relationship)
478
- @resource_class = resource_class
493
+ def initialize(resource, relationship)
494
+ @resource = resource
479
495
  @relationship = relationship
480
496
  end
481
497
 
482
498
  def message
483
- "#{@resource_class.name}: The requested included relationship \"#{@relationship}\" is not supported."
499
+ "#{@resource.class.name}: The requested included relationship \"#{@relationship}\" is not supported."
484
500
  end
485
501
  end
486
502
 
@@ -236,7 +236,7 @@ module Graphiti
236
236
  def handle_missing_sideload(name)
237
237
  if Graphiti.config.raise_on_missing_sideload
238
238
  raise Graphiti::Errors::InvalidInclude
239
- .new(name, @resource.type)
239
+ .new(@resource, name)
240
240
  end
241
241
  end
242
242
 
@@ -16,17 +16,19 @@ module Graphiti
16
16
  end
17
17
  end
18
18
 
19
- def associate_all(parent, children, association_name, type)
20
- children.each do |c|
21
- associate(parent, c, association_name, type)
22
- end
19
+ def associate_all(*args)
20
+ _associate(:associate_all, *args)
21
+ end
22
+
23
+ def associate(*args)
24
+ _associate(:associate, *args)
23
25
  end
24
26
 
25
- def associate(parent, child, association_name, type)
27
+ def _associate(meth, parent, other, association_name, type)
26
28
  child_resource = self.class.resource_for_model(parent)
27
29
  if child_resource.sideloads[association_name]
28
30
  child_resource.new.adapter
29
- .associate(parent, child, association_name, type)
31
+ .send(meth, parent, other, association_name, type)
30
32
  end
31
33
  end
32
34
 
@@ -55,10 +57,19 @@ module Graphiti
55
57
  end
56
58
  end
57
59
 
60
+ def resource_for_type(type)
61
+ resource = children.find { |c| c.type == type }
62
+ if resource.nil?
63
+ raise Errors::PolymorphicResourceChildNotFound.new(self, type: type)
64
+ else
65
+ resource
66
+ end
67
+ end
68
+
58
69
  def resource_for_model(model)
59
70
  resource = children.find { |c| model.is_a?(c.model) }
60
71
  if resource.nil?
61
- raise Errors::PolymorphicResourceChildNotFound.new(self, model)
72
+ raise Errors::PolymorphicResourceChildNotFound.new(self, model: model)
62
73
  else
63
74
  resource
64
75
  end
@@ -57,15 +57,15 @@ module Graphiti
57
57
  allow_sideload(name, opts, &blk)
58
58
  end
59
59
 
60
- def belongs_to_many(name, resource: nil, as:, &blk)
61
- resource = resource ||= Util::Class.infer_resource_class(self, name)
62
- sideload = resource.sideload(as)
63
-
64
- _resource = resource
65
- filter sideload.true_foreign_key, resource.attributes[:id][:type] do
66
- eq do |scope, value|
67
- _resource.new.adapter.belongs_to_many_filter(sideload, scope, value)
60
+ def polymorphic_has_many(name, opts = {}, as:, &blk)
61
+ opts[:foreign_key] ||= :"#{as}_id"
62
+ _model = model
63
+ has_many name, opts do
64
+ params do |hash|
65
+ hash[:filter][:"#{as}_type"] = _model.name
68
66
  end
67
+
68
+ instance_eval(&blk) if block_given?
69
69
  end
70
70
  end
71
71
 
@@ -32,6 +32,7 @@ module Graphiti
32
32
  @as = opts[:as]
33
33
  @link = opts[:link]
34
34
  @single = opts[:single]
35
+ apply_belongs_to_many_filter if type == :many_to_many
35
36
 
36
37
  # polymorphic-specific
37
38
  @group_name = opts[:group_name]
@@ -262,6 +263,16 @@ module Graphiti
262
263
 
263
264
  private
264
265
 
266
+ def apply_belongs_to_many_filter
267
+ _self = self
268
+ fk_type = parent_resource_class.attributes[:id][:type]
269
+ resource_class.filter true_foreign_key, fk_type do
270
+ eq do |scope, value|
271
+ _self.resource.adapter.belongs_to_many_filter(_self, scope, value)
272
+ end
273
+ end
274
+ end
275
+
265
276
  def load_options(parents, query)
266
277
  {}.tap do |opts|
267
278
  opts[:default_paginate] = false
@@ -15,6 +15,13 @@ class Graphiti::Util::Persistence
15
15
  @attributes.each_pair do |key, value|
16
16
  @attributes[key] = @resource.typecast(key, value, :writable)
17
17
  end
18
+
19
+ # Find the correct child resource for a given jsonapi type
20
+ if meta_type = @meta[:type].try(:to_sym)
21
+ if @resource.type != meta_type && @resource.polymorphic?
22
+ @resource = @resource.class.resource_for_type(meta_type).new
23
+ end
24
+ end
18
25
  end
19
26
 
20
27
  # Perform the actual save logic.
@@ -43,9 +43,10 @@ module Graphiti
43
43
  end
44
44
 
45
45
  def payload_for(sideload, relationship_payload)
46
- if sideload.polymorphic_parent?
47
- type = relationship_payload[:meta][:jsonapi_type]
48
- sideload = sideload.child_for_type(type.to_sym)
46
+ type = relationship_payload[:meta][:jsonapi_type].to_sym
47
+
48
+ if sideload.resource.type != type && sideload.polymorphic_parent?
49
+ sideload = sideload.child_for_type(type)
49
50
  end
50
51
  relationship_payload[:meta][:method] ||= :update
51
52
 
@@ -1,3 +1,3 @@
1
1
  module Graphiti
2
- VERSION = "1.0.alpha.19"
2
+ VERSION = "1.0.alpha.20"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphiti
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.alpha.19
4
+ version: 1.0.alpha.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-09-02 00:00:00.000000000 Z
11
+ date: 2018-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jsonapi-serializable