active_model_serializers_pg 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|