active_model_serializers_pg 0.0.6 → 0.0.7
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 +4 -4
- data/README.md +2 -0
- data/Rakefile +3 -0
- data/lib/active_model_serializers/adapter/json_api_pg.rb +35 -12
- data/lib/active_model_serializers_pg/version.rb +1 -1
- data/spec/serializer_spec.rb +15 -3
- data/spec/spec_helper.rb +7 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 709fe0bce48637cbd10e3f8a4cc66d9332da0a36ea2158153711c2f49bcdc82f
|
4
|
+
data.tar.gz: bbc3e6c16daf9b8c28ce8d105d1dc355c35b1188b935051447c6b5fab96acda0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c323f581ecea8145344d4fe95df91a76d548762de320a43513eb7081842d30b28e81fb33a4adc3cca173964d17ce5ba7c384e27043cf9aca68e0ca161b9b83b9
|
7
|
+
data.tar.gz: 076e6dad498e0d0533fe63f4a396099c61557c7b2a05a17ebe910f2caca61b11d4cf005351570e7a4579447e9c427ff7298b759f35a15bfe27749144bee44292
|
data/README.md
CHANGED
@@ -59,8 +59,10 @@ Here are some other details we support:
|
|
59
59
|
- `belongs_to`, `has_one`, and `has_many` associations.
|
60
60
|
- If you serialize an `enum` you get the string values, not integers.
|
61
61
|
- You can serialize an `alias`'d association.
|
62
|
+
- You can serialize an `alias_attribute`'d column.
|
62
63
|
- We preserve SQL ordering from a model's `default_scope`.
|
63
64
|
- We preserve SQL ordering attached to an association.
|
65
|
+
- When dasherizing we also dasherize json/jsonb/hstore contents (like standard AMS).
|
64
66
|
|
65
67
|
### Methods in Serializers and Models
|
66
68
|
|
data/Rakefile
CHANGED
@@ -77,7 +77,7 @@ module ActiveModelSerializers
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def self.warn_about_collection_serializer
|
80
|
-
msg = "You are using an ordinary AMS CollectionSerializer with the json_api_pg adapter, which probably means Rails is pointlessly loading all your ActiveRecord instances *and* running the
|
80
|
+
msg = "You are using an ordinary AMS CollectionSerializer with the json_api_pg adapter, which probably means Rails is pointlessly loading all your ActiveRecord instances *and* running the JSON-building query in Postgres."
|
81
81
|
if Object.const_defined? 'Rails'
|
82
82
|
Rails.logger.warn msg
|
83
83
|
else
|
@@ -105,8 +105,8 @@ end
|
|
105
105
|
# i.e. how you got here, not how you'd leave:
|
106
106
|
# "Reflection" seems to be the internal ActiveRecord lingo
|
107
107
|
# for a belongs_to or has_many relationship.
|
108
|
-
# (The public documentation calls these "associations"
|
109
|
-
# I think
|
108
|
+
# (The public documentation calls these "associations".
|
109
|
+
# I think older versions of Rails even used that internally,
|
110
110
|
# but nowadays the method names use "reflection".)
|
111
111
|
class JsonThing
|
112
112
|
attr_reader :ar_class, :full_name, :name, :serializer, :serializer_options, :json_key, :json_type, :reflection, :parent, :cte_name, :jbs_name
|
@@ -192,7 +192,7 @@ class JsonThing
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
-
# Each thing has
|
195
|
+
# Each thing has both a `cte_foo` CTE and a `jbs_foo` CTE.
|
196
196
|
# (jbs stands for "JSONBs" and is meant to take 3 chars like `cte`.)
|
197
197
|
# The former is just the relevant records,
|
198
198
|
# and the second builds the JSON object for each record.
|
@@ -447,16 +447,22 @@ class JsonApiPgSql
|
|
447
447
|
# Standard AMS dasherizes json/jsonb/hstore columns,
|
448
448
|
# so we have to do the same:
|
449
449
|
if ActiveModelSerializers.config.key_transform == :dash
|
450
|
-
|
451
|
-
|
450
|
+
cl = resource.ar_class.attribute_types[field.to_s]
|
451
|
+
if column_is_jsonb? cl
|
452
|
+
%Q{jsonb_dasherize("#{resource.table_name}"."#{field}")}
|
453
|
+
elsif column_is_jsonb_array? cl
|
454
|
+
# TODO: Could be faster:
|
455
|
+
# If we made the jsonb_dasherize function smarter so it could handle jsonb[],
|
456
|
+
# we wouldn't have to build a json object from the array then cast to jsonb[].
|
457
|
+
%Q{jsonb_dasherize(array_to_json("#{resource.table_name}"."#{field}")::jsonb)}
|
458
|
+
elsif column_is_castable_to_jsonb? cl
|
452
459
|
# Fortunately we can cast hstore to jsonb,
|
453
460
|
# which gives us a solution that works whether or not the hstore extension is installed.
|
454
461
|
# Defining an hstore_dasherize function would work only if the extension were present.
|
455
462
|
%Q{jsonb_dasherize("#{resource.table_name}"."#{field}"::jsonb)}
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
%Q{jsonb_dasherize("#{resource.table_name}"."#{field}"::jsonb)}
|
463
|
+
elsif column_is_castable_to_jsonb_array? cl
|
464
|
+
# TODO: Could be faster (see above):
|
465
|
+
%Q{jsonb_dasherize(array_to_json("#{resource.table_name}"."#{field}"::jsonb[])::jsonb)}
|
460
466
|
else
|
461
467
|
%Q{"#{resource.table_name}"."#{field}"}
|
462
468
|
end
|
@@ -466,6 +472,25 @@ class JsonApiPgSql
|
|
466
472
|
end
|
467
473
|
end
|
468
474
|
|
475
|
+
def column_is_jsonb?(column_class)
|
476
|
+
column_class.is_a? ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb
|
477
|
+
end
|
478
|
+
|
479
|
+
def column_is_jsonb_array?(column_class)
|
480
|
+
column_class.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array) and
|
481
|
+
column_class.subtype.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb)
|
482
|
+
end
|
483
|
+
|
484
|
+
def column_is_castable_to_jsonb?(column_class)
|
485
|
+
column_class.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Hstore) or
|
486
|
+
column_class.is_a?(self.class.json_column_type)
|
487
|
+
end
|
488
|
+
|
489
|
+
def column_is_castable_to_jsonb_array?(column_class)
|
490
|
+
column_class.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array) and
|
491
|
+
column_is_castable_to_jsonb?(column_class.subtype)
|
492
|
+
end
|
493
|
+
|
469
494
|
def select_resource_relationship_links(resource, reflection)
|
470
495
|
reflection.links.map {|link_name, link_parts|
|
471
496
|
<<~EOQ
|
@@ -603,8 +628,6 @@ class JsonApiPgSql
|
|
603
628
|
|
604
629
|
# See note in _jbs_name method for why we split each thing into two CTEs.
|
605
630
|
def include_cte(resource)
|
606
|
-
# Sometimes options[:fields] has plural keys and sometimes singular,
|
607
|
-
# so try both:
|
608
631
|
parent = resource.parent
|
609
632
|
<<~EOQ
|
610
633
|
SELECT DISTINCT ON ("#{resource.table_name}"."#{resource.primary_key}")
|
data/spec/serializer_spec.rb
CHANGED
@@ -215,9 +215,12 @@ describe 'ArraySerializer' do
|
|
215
215
|
let(:person) {
|
216
216
|
Person.create first_name: 'Test',
|
217
217
|
last_name: 'User',
|
218
|
-
options:
|
219
|
-
prefs:
|
220
|
-
settings:
|
218
|
+
options: { 'foo_foo': 'baz', bar: [{ 'jar_jar': 'binks' }] },
|
219
|
+
prefs: { 'foo_foo': 'baz', bar: [{ 'jar_jar': 'binks' }] },
|
220
|
+
settings: { 'foo_foo': 'bar' },
|
221
|
+
selfies: [ { 'photo_resolution': '200x200' } ],
|
222
|
+
portraits: [ { 'photo_resolution': '150x200' } ],
|
223
|
+
landscapes: [ { 'photo_resolution': '200x150' } ]
|
221
224
|
}
|
222
225
|
let(:options) { { each_serializer: PersonWithJsonSerializer } }
|
223
226
|
|
@@ -245,9 +248,18 @@ describe 'ArraySerializer' do
|
|
245
248
|
bar: [{ 'jar-jar' => 'binks'}],
|
246
249
|
'foo-foo' => 'baz',
|
247
250
|
},
|
251
|
+
selfies: [
|
252
|
+
{ 'photo-resolution' => '200x200' },
|
253
|
+
],
|
248
254
|
settings: {
|
249
255
|
'foo-foo' => 'bar'
|
250
256
|
},
|
257
|
+
portraits: [
|
258
|
+
{ 'photo-resolution' => '150x200' },
|
259
|
+
],
|
260
|
+
landscapes: [
|
261
|
+
{ 'photo-resolution' => '200x150' },
|
262
|
+
],
|
251
263
|
},
|
252
264
|
}
|
253
265
|
]
|
data/spec/spec_helper.rb
CHANGED
@@ -69,7 +69,13 @@ class PersonSerializer < ActiveModel::Serializer
|
|
69
69
|
end
|
70
70
|
|
71
71
|
class PersonWithJsonSerializer < ActiveModel::Serializer
|
72
|
-
attributes :id,
|
72
|
+
attributes :id,
|
73
|
+
:options, # json
|
74
|
+
:prefs, # jsonb
|
75
|
+
:settings, # hstore
|
76
|
+
:selfies, # json[]
|
77
|
+
:portraits, # jsonb[]
|
78
|
+
:landscapes # hstore[]
|
73
79
|
end
|
74
80
|
|
75
81
|
class Note < ActiveRecord::Base
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_model_serializers_pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul A. Jungwirth
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -226,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
226
226
|
- !ruby/object:Gem::Version
|
227
227
|
version: '0'
|
228
228
|
requirements: []
|
229
|
-
rubygems_version: 3.0.
|
229
|
+
rubygems_version: 3.0.8
|
230
230
|
signing_key:
|
231
231
|
specification_version: 4
|
232
232
|
summary: Harness the power of PostgreSQL when crafting JSON reponses
|