Skip to content

Commit 500250f

Browse files
glaucocustodionesaulov
authored andcommitted
Add .defined_schema method (#98)
1 parent ed483bd commit 500250f

File tree

4 files changed

+109
-3
lines changed

4 files changed

+109
-3
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Next (unreleased)
2+
3+
## Added
4+
* `.defined_schema` to return the schema that has been defined with `json_schema` ([@glaucocustodio][]) [#98](https://github.com/nesaulov/surrealist/pull/98)
5+
16
# 1.1.2
27

38
## Fixed
@@ -87,6 +92,7 @@
8792
* Allow nil values by default.
8893
* Allow nested objects.
8994

95+
[@glaucocustodio]: https://github.com/glaucocustodio
9096
[@nesaulov]: https://github.com/nesaulov
9197
[@AlessandroMinali]: https://github.com/AlessandroMinali
9298
[@nulldef]: https://github.com/nulldef

README.md

+12-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ to serialize nested objects and structures. [Introductory blogpost.](https://med
2727
* [Defining custom serializers](#defining-custom-serializers)
2828
* [Multiple serializers](#multiple-serializers)
2929
* [Build schema](#build-schema)
30+
* [Defined schema](#defined-schema)
3031
* [Working with ORMs](#working-with-orms)
3132
* [ActiveRecord](#activerecord)
3233
* [ROM](#rom)
@@ -260,19 +261,19 @@ you have to define yourself. DSL looks as follows
260261
class IncomeSerializer < Surrealist::Serializer
261262
serializer_context :current_user
262263
json_schema { { amount: Integer } }
263-
264+
264265
def amount
265266
current_user.guest? ? 100000000 : object.amount
266267
end
267268
end
268-
```
269+
```
269270
`.serializer_context` takes an array of symbols and dynamically defines instance methods
270271
that read values from the context hash. So `.serializer_context :current_user` will become
271272
``` ruby
272273
def current_user
273274
context[:current_user]
274275
end
275-
```
276+
```
276277
There is also an alias in the plural form: `.serializer_contexts`.
277278
### Multiple serializers
278279

@@ -321,6 +322,14 @@ Car.new.build_schema
321322
# => { age: 7, brand: "Toyota", doors: nil, horsepower: 140, fuel_system: "Direct injection", previous_owner: "John Doe" }
322323
```
323324

325+
### Defined schema
326+
Use the `.defined_schema` method to get the schema that has been defined with `json_schema`:
327+
328+
``` ruby
329+
User.defined_schema
330+
# => { name: String, age: Integer }
331+
```
332+
324333
### Working with ORMs
325334

326335
There are two kinds of return values of ORM methods: some return collections of objects, while others return instances.

lib/surrealist/class_methods.rb

+30
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ def json_schema(&_block)
5555
SchemaDefiner.call(self, yield)
5656
end
5757

58+
# A DSL method to return the defined schema.
59+
# @example DSL usage example
60+
# class Person
61+
# include Surrealist
62+
#
63+
# json_schema do
64+
# { name: String }
65+
# end
66+
#
67+
# def name
68+
# 'Parent'
69+
# end
70+
# end
71+
#
72+
# Person.defined_schema
73+
# # => { name: String }
74+
def defined_schema
75+
read_schema.tap do |schema|
76+
raise UnknownSchemaError if schema.nil?
77+
end
78+
end
79+
5880
# A DSL method to delegate schema in a declarative style. Must reference a valid
5981
# class that includes Surrealist
6082
#
@@ -101,9 +123,17 @@ def delegate_surrealization_to(klass)
101123
def surrealize_with(klass, tag: Surrealist::VarsHelper::DEFAULT_TAG)
102124
if klass < Surrealist::Serializer
103125
Surrealist::VarsHelper.add_serializer(self, klass, tag: tag)
126+
instance_variable_set(VarsHelper::PARENT_VARIABLE, klass.defined_schema)
104127
else
105128
raise ArgumentError, "#{klass} should be inherited from Surrealist::Serializer"
106129
end
107130
end
131+
132+
private
133+
134+
def read_schema
135+
instance_variable_get(VarsHelper::INSTANCE_VARIABLE) ||
136+
instance_variable_get(VarsHelper::PARENT_VARIABLE)
137+
end
108138
end
109139
end

spec/schema_spec.rb

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
class WithSchema
2+
include Surrealist
3+
4+
json_schema { { name: String, age: Integer } }
5+
6+
def name
7+
'John'
8+
end
9+
10+
def age
11+
21
12+
end
13+
end
14+
15+
class WithoutSchema
16+
include Surrealist
17+
end
18+
19+
class PersonSerializer < Surrealist::Serializer
20+
json_schema { { age: Integer } }
21+
22+
def age
23+
20
24+
end
25+
end
26+
27+
class WithCustomSerializer
28+
include Surrealist
29+
attr_reader :age
30+
31+
surrealize_with PersonSerializer
32+
33+
def initialize(age)
34+
@age = age
35+
end
36+
end
37+
38+
RSpec.describe Surrealist do
39+
describe '.defined_schema' do
40+
context 'json schema defined' do
41+
context 'using custom serializer' do
42+
it 'returns the defined json_schema' do
43+
expect(PersonSerializer.defined_schema).to eq(age: Integer)
44+
expect(WithCustomSerializer.defined_schema).to eq(age: Integer)
45+
end
46+
end
47+
48+
context 'not using custom serializer' do
49+
it 'returns the defined json_schema' do
50+
expect(WithSchema.defined_schema).to eq(name: String, age: Integer)
51+
end
52+
end
53+
end
54+
55+
context 'json schema not defined' do
56+
it 'raises UnknownSchemaError' do
57+
expect { WithoutSchema.defined_schema }.to raise_error(Surrealist::UnknownSchemaError)
58+
end
59+
end
60+
end
61+
end

0 commit comments

Comments
 (0)