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

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: 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