Skip to content

Commit f49ce4d

Browse files
committed
feat: infer polymorphic types
1 parent 9c1ec81 commit f49ce4d

File tree

10 files changed

+42
-19
lines changed

10 files changed

+42
-19
lines changed

Gemfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ ruby "3.3.2"
44

55
gemspec
66

7-
gem "jsonapi-resources", "~> 0.1"
7+
gem "jsonapi-resources",
8+
"0.11.0.beta2",
9+
git: "https://github.com/cerebris/jsonapi-resources",
10+
branch: "v0-11-dev",
11+
ref: "d3c094b"
812

913
# # The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
1014
gem "sprockets-rails"

Gemfile.lock

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
GIT
2+
remote: https://github.com/cerebris/jsonapi-resources
3+
revision: d3c094b46a38650e583f40adc86474827b606fc7
4+
ref: d3c094b
5+
branch: v0-11-dev
6+
specs:
7+
jsonapi-resources (0.11.0.beta2)
8+
activerecord (>= 5.1)
9+
concurrent-ruby
10+
railties (>= 5.1)
11+
sorted_set
12+
113
PATH
214
remote: .
315
specs:
@@ -103,10 +115,6 @@ GEM
103115
rdoc (>= 4.0.0)
104116
reline (>= 0.4.2)
105117
json (2.9.1)
106-
jsonapi-resources (0.10.7)
107-
activerecord (>= 4.1)
108-
concurrent-ruby
109-
railties (>= 4.1)
110118
language_server-protocol (3.17.0.3)
111119
logger (1.6.5)
112120
loofah (2.24.0)
@@ -194,6 +202,7 @@ GEM
194202
zeitwerk (~> 2.6)
195203
rainbow (3.1.1)
196204
rake (13.2.1)
205+
rbtree (0.4.6)
197206
rdoc (6.10.0)
198207
psych (>= 4.0.0)
199208
regexp_parser (2.10.0)
@@ -242,6 +251,10 @@ GEM
242251
rubocop (~> 1.51)
243252
ruby-progressbar (1.13.0)
244253
securerandom (0.4.1)
254+
set (1.1.1)
255+
sorted_set (1.0.3)
256+
rbtree
257+
set (~> 1.0)
245258
sprockets (4.2.1)
246259
concurrent-ruby (~> 1.0)
247260
rack (>= 2.2.4, < 4)
@@ -274,7 +287,7 @@ PLATFORMS
274287

275288
DEPENDENCIES
276289
debug
277-
jsonapi-resources (~> 0.1)
290+
jsonapi-resources (= 0.11.0.beta2)!
278291
jsonapi-resources-anchor!
279292
pg (~> 1.5)
280293
puma (>= 5.0)

lib/anchor/resource.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,15 @@ def anchor_relationships_properties(included_fields:)
164164
# @param name [String, Symbol]
165165
# @return [Anchor::Types::Reference, Anchor::Types::Array<Anchor::Types::Reference>, Anchor::Types::Maybe<Anchor::Types::Reference>]
166166
def relationship_type_for(rel, resource_klass, name)
167-
ref = Anchor::Types::Reference.new(resource_klass.anchor_schema_name)
167+
rel_type = if rel.polymorphic? && rel.respond_to?(:polymorphic_types) # 0.11.0.beta2
168+
resource_klasses = rel.polymorphic_types.map { |t| resource_klass_for(t) }
169+
Anchor::Types::Union.new(resource_klasses.map { |rk| Anchor::Types::Reference.new(rk.anchor_schema_name) })
170+
elsif rel.polymorphic? && rel.class.respond_to?(:polymorphic_types) # TODO: < 0.11.0.beta2
171+
resource_klasses = rel.class.polymorphic_types.map { |t| resource_klass_for(t) }
172+
Anchor::Types::Union.new(resource_klasses.map { |rk| Anchor::Types::Reference.new(rk.anchor_schema_name) })
173+
end
174+
175+
rel_type ||= Anchor::Types::Reference.new(resource_klass.anchor_schema_name)
168176
model_relationship_name = (rel.options[:relation_name] || name).to_s
169177
reflection = _model_class.try(:reflections).try(:[], model_relationship_name)
170178
wrapper = if reflection
@@ -173,7 +181,7 @@ def relationship_type_for(rel, resource_klass, name)
173181
Anchor::Types::Inference::JSONAPI.wrapper_from_relationship(rel)
174182
end
175183

176-
wrapper.call(ref)
184+
wrapper.call(rel_type)
177185
end
178186
end
179187
# rubocop:enable Layout/LineLength

spec/example/app/resources/comment_resource.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ class CommentResource < ApplicationResource
55

66
relationship :user, to: :one, description: "Author of the comment."
77
relationship :deleted_by, to: :one, class_name: "User"
8-
relationship :commentable,
9-
Types::Relationship.new(resources: [UserResource, PostResource], null: true),
10-
polymorphic: true,
11-
to: :one
8+
relationship :commentable, polymorphic: true, to: :one
129

1310
def self.anchor_fetchable_fields(context)
1411
case context[:role]

spec/example/config/environments/development.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
# since you don't have to restart the web server when you make code changes.
99
config.enable_reloading = true
1010

11-
# Do not eager load code on boot.
12-
config.eager_load = false
11+
# Eager load code on boot.
12+
config.eager_load = true
1313

1414
# Show full error reports.
1515
config.consider_all_requests_local = true

spec/example/config/environments/test.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
# this is usually not necessary, and can slow down your test suite. However, it's
1616
# recommended that you enable it in continuous integration systems to ensure eager
1717
# loading is working properly before deploying your code.
18-
config.eager_load = ENV["CI"].present?
18+
# config.eager_load = ENV["CI"].present?
19+
config.eager_load = true
1920

2021
# Configure public file server for tests with Cache-Control for performance.
2122
config.public_file_server.enabled = true
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"$schema":"https://json-schema.org/draft-07/schema","title":"Schema","type":"object","properties":{"comment":{"$ref":"#/$defs/Comment"},"user":{"$ref":"#/$defs/User"},"post":{"$ref":"#/$defs/Post"},"exhaustive":{"$ref":"#/$defs/Exhaustive"}},"required":["comment","user","post","exhaustive"],"additionalProperties":false,"$defs":{"Comment":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["comments"]},"text":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"relationships":{"type":"object","properties":{"user":{"$ref":"#/$defs/User"},"deletedBy":{"$ref":"#/$defs/User"},"commentable":{"oneOf":[{"$ref":"#/$defs/User"},{"$ref":"#/$defs/Post"}]}},"required":["user"],"additionalProperties":false}},"required":["id","type","text","createdAt","updatedAt","relationships"],"additionalProperties":false},"User":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["users"]},"name":{"type":"string"},"role":{"enum":[{"value":"admin"},{"value":"content_creator"},{"value":"external"},{"value":"guest"},{"value":"system"}]},"relationships":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/$defs/Comment"}},"posts":{"type":"array","items":{"$ref":"#/$defs/Post"}}},"required":["comments","posts"],"additionalProperties":false}},"required":["id","type","name","role","relationships"],"additionalProperties":false},"Post":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["posts"]},"description":{"type":"string"},"relationships":{"type":"object","properties":{"user":{"$ref":"#/$defs/User"},"comments":{"type":"array","items":{"$ref":"#/$defs/Comment"}},"participants":{"type":"array","items":{"$ref":"#/$defs/User"}}},"required":["user","comments","participants"],"additionalProperties":false}},"required":["id","type","description","relationships"],"additionalProperties":false},"Exhaustive":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["exhaustives"]},"assertedString":{"type":"string"},"assertedNumber":{"type":"number"},"assertedBoolean":{"type":"boolean"},"assertedNull":{"type":"null"},"assertedUnknown":{},"assertedObject":{"type":"object","properties":{"a":{"enum":["a"]},"b-dash":{"enum":[1]},"c":{"oneOf":[{"type":"string"},{"type":"null"}]},"d_optional":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["a","b-dash","c"],"additionalProperties":false},"assertedMaybeObject":{"oneOf":[{"type":"object","properties":{"a":{"enum":["a"]},"b-dash":{"enum":[1]},"c":{"oneOf":[{"type":"string"},{"type":"null"}]},"d_optional":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["a","b-dash","c"],"additionalProperties":false},{"type":"null"}]},"assertedArrayRecord":{"type":"array","items":{"type":"object","additionalProperties":"true"}},"assertedUnion":{"oneOf":[{"type":"string"},{"type":"number"}]},"withDescription":{"type":"string"},"inferredUnknown":{},"uuid":{"type":"string"},"string":{"type":"string"},"maybeString":{"type":"string"},"text":{"type":"string"},"integer":{"type":"number"},"float":{"type":"number"},"decimal":{"type":"string"},"datetime":{"type":"string"},"timestamp":{"type":"string"},"time":{"type":"string"},"date":{"type":"string"},"boolean":{"type":"boolean"},"arrayString":{"type":"array","items":{"type":"string"}},"maybeArrayString":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"json":{"type":"object","additionalProperties":"true"},"jsonb":{"type":"object","additionalProperties":"true"},"daterange":{},"enum":{},"virtualUpcasedString":{"oneOf":[{"type":"string"},{"type":"null"}]},"loljk":{"enum":["never"]},"delegatedMaybeString":{"type":"string"},"modelOverridden":{},"resourceOverridden":{},"withComment":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","type","assertedString","assertedNumber","assertedBoolean","assertedNull","assertedUnknown","assertedObject","assertedMaybeObject","assertedArrayRecord","assertedUnion","withDescription","inferredUnknown","uuid","string","maybeString","text","integer","float","decimal","datetime","timestamp","time","date","boolean","arrayString","maybeArrayString","json","jsonb","daterange","enum","virtualUpcasedString","loljk","delegatedMaybeString","modelOverridden","resourceOverridden","withComment"],"additionalProperties":false}}}
1+
{"$schema":"https://json-schema.org/draft-07/schema","title":"Schema","type":"object","properties":{"comment":{"$ref":"#/$defs/Comment"},"user":{"$ref":"#/$defs/User"},"post":{"$ref":"#/$defs/Post"},"exhaustive":{"$ref":"#/$defs/Exhaustive"}},"required":["comment","user","post","exhaustive"],"additionalProperties":false,"$defs":{"Comment":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["comments"]},"text":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"relationships":{"type":"object","properties":{"user":{"$ref":"#/$defs/User"},"deletedBy":{"$ref":"#/$defs/User"},"commentable":{"oneOf":[{"$ref":"#/$defs/Post"}]}},"required":["user"],"additionalProperties":false}},"required":["id","type","text","createdAt","updatedAt","relationships"],"additionalProperties":false},"User":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["users"]},"name":{"type":"string"},"role":{"enum":[{"value":"admin"},{"value":"content_creator"},{"value":"external"},{"value":"guest"},{"value":"system"}]},"relationships":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/$defs/Comment"}},"posts":{"type":"array","items":{"$ref":"#/$defs/Post"}}},"required":["comments","posts"],"additionalProperties":false}},"required":["id","type","name","role","relationships"],"additionalProperties":false},"Post":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["posts"]},"description":{"type":"string"},"relationships":{"type":"object","properties":{"user":{"$ref":"#/$defs/User"},"comments":{"type":"array","items":{"$ref":"#/$defs/Comment"}},"participants":{"type":"array","items":{"$ref":"#/$defs/User"}}},"required":["user","comments","participants"],"additionalProperties":false}},"required":["id","type","description","relationships"],"additionalProperties":false},"Exhaustive":{"type":"object","properties":{"id":{"type":"number"},"type":{"enum":["exhaustives"]},"assertedString":{"type":"string"},"assertedNumber":{"type":"number"},"assertedBoolean":{"type":"boolean"},"assertedNull":{"type":"null"},"assertedUnknown":{},"assertedObject":{"type":"object","properties":{"a":{"enum":["a"]},"b-dash":{"enum":[1]},"c":{"oneOf":[{"type":"string"},{"type":"null"}]},"d_optional":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["a","b-dash","c"],"additionalProperties":false},"assertedMaybeObject":{"oneOf":[{"type":"object","properties":{"a":{"enum":["a"]},"b-dash":{"enum":[1]},"c":{"oneOf":[{"type":"string"},{"type":"null"}]},"d_optional":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["a","b-dash","c"],"additionalProperties":false},{"type":"null"}]},"assertedArrayRecord":{"type":"array","items":{"type":"object","additionalProperties":"true"}},"assertedUnion":{"oneOf":[{"type":"string"},{"type":"number"}]},"withDescription":{"type":"string"},"inferredUnknown":{},"uuid":{"type":"string"},"string":{"type":"string"},"maybeString":{"type":"string"},"text":{"type":"string"},"integer":{"type":"number"},"float":{"type":"number"},"decimal":{"type":"string"},"datetime":{"type":"string"},"timestamp":{"type":"string"},"time":{"type":"string"},"date":{"type":"string"},"boolean":{"type":"boolean"},"arrayString":{"type":"array","items":{"type":"string"}},"maybeArrayString":{"oneOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"json":{"type":"object","additionalProperties":"true"},"jsonb":{"type":"object","additionalProperties":"true"},"daterange":{},"enum":{},"virtualUpcasedString":{"oneOf":[{"type":"string"},{"type":"null"}]},"loljk":{"enum":["never"]},"delegatedMaybeString":{"type":"string"},"modelOverridden":{},"resourceOverridden":{},"withComment":{"oneOf":[{"type":"string"},{"type":"null"}]}},"required":["id","type","assertedString","assertedNumber","assertedBoolean","assertedNull","assertedUnknown","assertedObject","assertedMaybeObject","assertedArrayRecord","assertedUnion","withDescription","inferredUnknown","uuid","string","maybeString","text","integer","float","decimal","datetime","timestamp","time","date","boolean","arrayString","maybeArrayString","json","jsonb","daterange","enum","virtualUpcasedString","loljk","delegatedMaybeString","modelOverridden","resourceOverridden","withComment"],"additionalProperties":false}}}

spec/example/test/files/multifile/Comment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type Model = {
1313
/** Author of the comment. */
1414
user: User;
1515
deletedBy?: User;
16-
commentable?: User | Post;
16+
commentable?: Post;
1717
};
1818
};
1919

spec/example/test/files/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export type Comment = {
1818
/** Author of the comment. */
1919
user: User;
2020
deletedBy?: User;
21-
commentable?: User | Post;
21+
commentable?: Post;
2222
};
2323
};
2424

spec/example/test/files/test_schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type Comment = {
1515
updatedAt: string;
1616
relationships: {
1717
deletedBy?: User;
18-
commentable?: User | Post;
18+
commentable?: Post;
1919
};
2020
};
2121

0 commit comments

Comments
 (0)