rails_json_serializer 1.2.0 → 2.0.0
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/lib/serializer.rb +2 -4
- data/lib/serializer/model_serializer.rb +188 -0
- metadata +2 -3
- data/lib/serializer/application_serializer.rb +0 -10
- data/lib/serializer/concern.rb +0 -244
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd9c2225a4d011180d3faec0e67fc4969af7aec11c16221fa02f4a5115f83e7a
|
4
|
+
data.tar.gz: 942a32755c097539a0a777f958aaba7b053c31f615db0f6bda6ddb41a1ab8fdb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cda83139a44087c474c4b64500586227558b39483e747f6903ed8551f9e92d786641a5ca14c726819291579be6334e6db1800a1a89f5c3c45cdbcd94d2466aa5
|
7
|
+
data.tar.gz: 6b809793573a8749e3ac44c0240a0dbda9bcd0ef4cd3e7516ccd30d3952ea76d472689bf7cfcc9ded2dfb15dd37c49c0a59bd980d6be236611484c56138b001b
|
data/lib/serializer.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
|
2
|
-
require_relative 'serializer/application_serializer'
|
1
|
+
require_relative 'serializer/model_serializer'
|
3
2
|
Dir[File.join(Rails.root, 'app', 'serializers', '**', '*.rb')].each {|file| require file }
|
4
3
|
require_relative 'serializer/configuration'
|
5
|
-
require_relative 'serializer/concern'
|
6
4
|
|
7
5
|
module Serializer
|
8
6
|
# config src: http://lizabinante.com/blog/creating-a-configurable-ruby-gem/
|
@@ -24,4 +22,4 @@ module Serializer
|
|
24
22
|
end
|
25
23
|
|
26
24
|
# include the extension
|
27
|
-
ActiveRecord::Base.send(:include, Serializer::Concern)
|
25
|
+
# ActiveRecord::Base.send(:include, Serializer::Concern)
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module ModelSerializer
|
2
|
+
# klazz is that class object that included this module
|
3
|
+
def self.included klass
|
4
|
+
# START CLASS EVAL
|
5
|
+
klass.class_eval do
|
6
|
+
if self.const_defined?("#{klass.name}Serializer")
|
7
|
+
serializer_klass = "#{klass.name}Serializer".constantize
|
8
|
+
serializer_query_names = serializer_klass.public_instance_methods
|
9
|
+
if klass.superclass.const_defined?("SERIALIZER_QUERY_KEYS_CACHE")
|
10
|
+
self.const_set('SERIALIZER_QUERY_KEYS_CACHE', (serializer_query_names + klass.superclass::SERIALIZER_QUERY_KEYS_CACHE).uniq)
|
11
|
+
else
|
12
|
+
self.const_set('SERIALIZER_QUERY_KEYS_CACHE', serializer_query_names)
|
13
|
+
end
|
14
|
+
# Inject class methods, will have access to those queries on the class.
|
15
|
+
klass.send(:extend, serializer_klass)
|
16
|
+
|
17
|
+
# no need to define it if inheriting class has defined it OR has been manually overridden.
|
18
|
+
# CLASS METHODS
|
19
|
+
klass.send(:define_singleton_method, :serializer) do |opts = {}|
|
20
|
+
query = opts[:json_query_override].present? ? self.send(opts[:json_query_override], opts) : serializer_query(opts)
|
21
|
+
if Serializer.configuration.enable_includes && query[:include].present? && !opts[:skip_eager_loading]
|
22
|
+
includes(generate_includes_from_json_query(query)).as_json(query)
|
23
|
+
else
|
24
|
+
# Have to use 'all' gets stack level too deep otherwise. Not sure why.
|
25
|
+
all.as_json(query)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
klass.send(:define_singleton_method, :generate_includes_from_json_query) do |options = {}, klass = nil|
|
30
|
+
query_filter = {}
|
31
|
+
klass = self if klass.nil?
|
32
|
+
if options[:include].present? && !options[:skip_eager_loading]
|
33
|
+
options[:include].each do |include_key, include_hash|
|
34
|
+
next if include_hash[:skip_eager_loading] == true
|
35
|
+
# Will 'next' if there is a scope that takes arguments, an instance-dependent scope.
|
36
|
+
# Can't eager load when assocation has a instance condition for it's associative scope.
|
37
|
+
# Might not be a real assocation
|
38
|
+
next if klass.reflect_on_association(include_key).nil?
|
39
|
+
next if klass.reflect_on_association(include_key).scope&.arity&.nonzero?
|
40
|
+
query_filter[include_key] = {}
|
41
|
+
next if include_hash.none?
|
42
|
+
query_filter[include_key] = generate_includes_from_json_query(include_hash, klass.reflect_on_association(include_key).klass)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
# Does not include data, just eager-loads. Useful when methods need assocations, but you don't need association data.
|
46
|
+
if options[:eager_include].present?
|
47
|
+
options[:eager_include].each do |include_key|
|
48
|
+
# Will 'next' if there is a scope that takes arguments, an instance-dependent scope.
|
49
|
+
# Can't eager load when assocation has a instance condition for it's associative scope.
|
50
|
+
# Might not be a real assocation
|
51
|
+
next if klass.reflect_on_association(include_key).nil?
|
52
|
+
next if klass.reflect_on_association(include_key).scope&.arity&.nonzero?
|
53
|
+
query_filter[include_key] ||= {}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
return query_filter
|
57
|
+
end
|
58
|
+
|
59
|
+
klass.send(:define_singleton_method, :as_json_associations_alias_fix) do |options, data, opts = {}|
|
60
|
+
if data
|
61
|
+
# Depth is almost purely for debugging purposes
|
62
|
+
opts[:depth] ||= 0
|
63
|
+
if options[:include].present?
|
64
|
+
options[:include].each do |include_key, include_hash|
|
65
|
+
# The includes doesn't have to have a hash attached. Skip it if it doesn't.
|
66
|
+
next if include_hash.nil?
|
67
|
+
data_key = include_key.to_s
|
68
|
+
if include_hash[:as].present?
|
69
|
+
if include_hash[:as].to_s == include_key.to_s
|
70
|
+
raise "Serializer: Cannot alias json query association to have the same as the original key; as: #{include_hash[:as].to_s}; original_key: #{include_key.to_s} on self: #{name}"
|
71
|
+
end
|
72
|
+
alias_name = include_hash[:as]
|
73
|
+
data[alias_name.to_s] = data[include_key.to_s]
|
74
|
+
data.delete(include_key.to_s)
|
75
|
+
data_key = alias_name.to_s
|
76
|
+
end
|
77
|
+
# At this point, the data could be an array of objects, with no as_json options.
|
78
|
+
if !data[data_key].is_a?(Array)
|
79
|
+
data[data_key] = as_json_associations_alias_fix(include_hash, data[data_key], {depth: opts[:depth] + 1})
|
80
|
+
else
|
81
|
+
data[data_key].each_with_index do |value,i|
|
82
|
+
data[data_key][i] = as_json_associations_alias_fix(include_hash, value, {depth: opts[:depth] + 1})
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
return data
|
89
|
+
end
|
90
|
+
|
91
|
+
# no need to define it if inheriting class has defined it OR has been manually overridden.
|
92
|
+
# INSTANCE Methods
|
93
|
+
|
94
|
+
|
95
|
+
klass.send(:define_method, :as_json) do |options = {}|
|
96
|
+
# Not caching records that don't have IDs.
|
97
|
+
if !Serializer.configuration.disable_model_caching && self.id && options[:cache_key].present? && !(options.key?(:cache_for) && options[:cache_for].nil?)
|
98
|
+
cache_key = "#{self.class.name}_____#{options[:cache_key]}___#{self.id}"
|
99
|
+
if Rails.cache.exist?(cache_key)
|
100
|
+
Rails.logger.info "Serializer: Cache reading #{cache_key}" if Serializer.configuration.debug
|
101
|
+
return Rails.cache.read(cache_key)
|
102
|
+
else
|
103
|
+
data = super(options)
|
104
|
+
data = self.class.as_json_associations_alias_fix(options, data)
|
105
|
+
begin
|
106
|
+
Rails.logger.info "Serializer: Caching #{cache_key} for #{(options[:cache_for] || Serializer.configuration.default_cache_time)} minutes." if Serializer.configuration.debug
|
107
|
+
Rails.cache.write(cache_key, data, expires_in: (options[:cache_for] || Serializer.configuration.default_cache_time).minute)
|
108
|
+
rescue Exception => e
|
109
|
+
Rails.logger.error "Serializer: Internal Server Error on #{self.class}#as_json ID: #{self.id} for cache key: #{cache_key}"
|
110
|
+
Rails.logger.error e.class
|
111
|
+
Rails.logger.error e.message
|
112
|
+
Rails.logger.error e.backtrace
|
113
|
+
end
|
114
|
+
return data
|
115
|
+
end
|
116
|
+
else
|
117
|
+
if Serializer.configuration.debug && !Serializer.configuration.disable_model_caching && self.id && options[:cache_key].present? && options.key?(:cache_for) && options[:cache_for].nil?
|
118
|
+
Rails.logger.info "Serializer: Caching #{cache_key} NOT caching due to `cache_for: nil`"
|
119
|
+
end
|
120
|
+
data = super(options)
|
121
|
+
data = self.class.as_json_associations_alias_fix(options, data)
|
122
|
+
return data
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
if !klass.method_defined?(:serializer)
|
127
|
+
klass.send(:define_method, :serializer) do |opts = {}|
|
128
|
+
query = opts[:json_query_override].present? ? self.class.send(opts[:json_query_override], opts) : self.class.serializer_query(opts)
|
129
|
+
if Serializer.configuration.enable_includes && query[:include].present? && self.class.column_names.include?('id') && self.id.present? && !opts[:skip_eager_loading] && self.respond_to?(:persisted?) && self.persisted?
|
130
|
+
# It's an extra SQL call, but most likely worth it to pre-load associations
|
131
|
+
self.class.includes(self.class.generate_includes_from_json_query(query)).find(self.id).as_json(query)
|
132
|
+
else
|
133
|
+
as_json(query)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# # SHOULD NOT BE OVERRIDDEN.
|
139
|
+
klass.send(:define_method, :clear_serializer_cache) do
|
140
|
+
if self.class.const_defined?("SERIALIZER_QUERY_KEYS_CACHE")
|
141
|
+
self.class::SERIALIZER_QUERY_KEYS_CACHE.each do |query_name|
|
142
|
+
cache_key = "#{self.class.name}_____#{query_name}___#{self.id}"
|
143
|
+
Rails.logger.info "Serializer: CLEARING CACHE KEY: #{cache_key}" if Serializer.configuration.debug
|
144
|
+
Rails.cache.delete(cache_key)
|
145
|
+
end
|
146
|
+
return true
|
147
|
+
else
|
148
|
+
# if Serializer.configuration.debug
|
149
|
+
Rails.logger.error(
|
150
|
+
"""
|
151
|
+
ERROR. COULD NOT CLEAR SERIALIZER CACHE FOR: Class #{self.class.name}
|
152
|
+
Serializer: Class #{self.class.name} may not have the serializer module #{self.class.name}Serializer defined.
|
153
|
+
Nor was it defined on an inheriting class.
|
154
|
+
"""
|
155
|
+
)
|
156
|
+
# end
|
157
|
+
return nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
serializer_query_names.each do |query_name|
|
162
|
+
serializer_name = query_name[/(?<name>.+)_query/, :name]
|
163
|
+
if serializer_name.nil?
|
164
|
+
Rails.logger.error "Serializer: #{serializer_klass.name} method #{query_name} does not end in '(.+)_query', as is expected of serializers" if Serializer.configuration.debug
|
165
|
+
next
|
166
|
+
end
|
167
|
+
if serializer_name == 'serializer'
|
168
|
+
# No longer necessary to add here. We've added them above.
|
169
|
+
# klass.send(:define_method, serializer_name) do |opts = {}|
|
170
|
+
# super({json_query_override: query_name}.merge(opts))
|
171
|
+
# end
|
172
|
+
# klass.send(:define_singleton_method, serializer_name) do |opts = {}|
|
173
|
+
# super({json_query_override: query_name}.merge(opts))
|
174
|
+
# end
|
175
|
+
else
|
176
|
+
klass.send(:define_method, serializer_name) do |opts = {}|
|
177
|
+
serializer({json_query_override: query_name}.merge(opts))
|
178
|
+
end
|
179
|
+
klass.send(:define_singleton_method, serializer_name) do |opts = {}|
|
180
|
+
serializer({json_query_override: query_name}.merge(opts))
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
# END CLASS EVAL
|
187
|
+
end
|
188
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_json_serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- benjamin.dana.software.dev@gmail.com
|
@@ -115,9 +115,8 @@ extensions: []
|
|
115
115
|
extra_rdoc_files: []
|
116
116
|
files:
|
117
117
|
- lib/serializer.rb
|
118
|
-
- lib/serializer/application_serializer.rb
|
119
|
-
- lib/serializer/concern.rb
|
120
118
|
- lib/serializer/configuration.rb
|
119
|
+
- lib/serializer/model_serializer.rb
|
121
120
|
homepage: https://github.com/danabr75/rails_json_serializer
|
122
121
|
licenses:
|
123
122
|
- LGPL-3.0-only
|
data/lib/serializer/concern.rb
DELETED
@@ -1,244 +0,0 @@
|
|
1
|
-
module Serializer
|
2
|
-
DELETE_MATCHED_SUPPORTED_CACHE_TYPES = [:memory_store, :file_store]
|
3
|
-
module Concern
|
4
|
-
# ActiveSupport extend src: https://stackoverflow.com/questions/2328984/rails-extending-activerecordbase
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
# START MODEL INSTANCE METHODS
|
8
|
-
def clear_serializer_cache
|
9
|
-
if self.class.const_defined?("SERIALIZER_QUERY_KEYS_CACHE")
|
10
|
-
|
11
|
-
# list_of_serializer_query_names = "#{self.class.name}::SERIALIZER_QUERY_KEYS_CACHE".constantize
|
12
|
-
self.class.get_cumulatively_inherited_serializer_query_list.each do |query_name|
|
13
|
-
cache_key = "#{self.class.name}_____#{query_name}___#{self.id}"
|
14
|
-
Rails.logger.info "Serializer: CLEARING CACHE KEY: #{cache_key}" if Serializer.configuration.debug
|
15
|
-
Rails.cache.delete(cache_key)
|
16
|
-
end
|
17
|
-
return true
|
18
|
-
else
|
19
|
-
# if Serializer.configuration.debug
|
20
|
-
Rails.logger.error(
|
21
|
-
"""
|
22
|
-
ERROR. COULD NOT CLEAR SERIALIZER CACHE FOR: Class #{self.class.name}
|
23
|
-
Serializer: Class #{self.class.name} may not have the serializer module #{self.class.name}Serializer defined.
|
24
|
-
Nor was it defined on an inheriting class.
|
25
|
-
"""
|
26
|
-
)
|
27
|
-
# end
|
28
|
-
return nil
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def as_json options = {}
|
33
|
-
# Not caching records that don't have IDs.
|
34
|
-
if !Serializer.configuration.disable_model_caching && self.id && options[:cache_key].present? && !(options.key?(:cache_for) && options[:cache_for].nil?)
|
35
|
-
cache_key = "#{self.class.name}_____#{options[:cache_key]}___#{self.id}"
|
36
|
-
if Rails.cache.exist?(cache_key)
|
37
|
-
Rails.logger.info "Serializer: Cache reading #{cache_key}" if Serializer.configuration.debug
|
38
|
-
return Rails.cache.read(cache_key)
|
39
|
-
else
|
40
|
-
data = super(options)
|
41
|
-
data = self.class.as_json_associations_alias_fix(options, data)
|
42
|
-
begin
|
43
|
-
Rails.logger.info "Serializer: Caching #{cache_key} for #{(options[:cache_for] || Serializer.configuration.default_cache_time)} minutes." if Serializer.configuration.debug
|
44
|
-
Rails.cache.write(cache_key, data, expires_in: (options[:cache_for] || Serializer.configuration.default_cache_time).minute)
|
45
|
-
rescue Exception => e
|
46
|
-
Rails.logger.error "Serializer: Internal Server Error on #{self.class}#as_json ID: #{self.id} for cache key: #{cache_key}"
|
47
|
-
Rails.logger.error e.class
|
48
|
-
Rails.logger.error e.message
|
49
|
-
Rails.logger.error e.backtrace
|
50
|
-
end
|
51
|
-
return data
|
52
|
-
end
|
53
|
-
else
|
54
|
-
if Serializer.configuration.debug && !Serializer.configuration.disable_model_caching && self.id && options[:cache_key].present? && options.key?(:cache_for) && options[:cache_for].nil?
|
55
|
-
Rails.logger.info "Serializer: Caching #{cache_key} NOT caching due to `cache_for: nil`"
|
56
|
-
end
|
57
|
-
data = super(options)
|
58
|
-
data = self.class.as_json_associations_alias_fix(options, data)
|
59
|
-
return data
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# Can override the query, using the options. ex: {json_query_override: :tiny_serializer_query}
|
64
|
-
def serializer opts = {}
|
65
|
-
query = opts[:json_query_override].present? ? self.class.send(opts[:json_query_override], opts) : self.class.serializer_query(opts)
|
66
|
-
if Serializer.configuration.enable_includes && query[:include].present? && self.class.column_names.include?('id') && self.id.present? && !opts[:skip_eager_loading] && self.respond_to?(:persisted?) && self.persisted?
|
67
|
-
# It's an extra SQL call, but most likely worth it to pre-load associations
|
68
|
-
self.class.includes(self.class.generate_includes_from_json_query(query)).find(self.id).as_json(query)
|
69
|
-
else
|
70
|
-
as_json(query)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
# END MODEL INSTANCE METHODS
|
74
|
-
|
75
|
-
class_methods do
|
76
|
-
# START MODEL CLASS METHODS
|
77
|
-
def inherited subclass
|
78
|
-
if subclass.const_defined?("#{subclass.name}Serializer")
|
79
|
-
serializer_klass = "#{subclass.name}Serializer".constantize
|
80
|
-
|
81
|
-
if serializer_klass.class == Module
|
82
|
-
if !serializer_klass.const_defined?("SerializerClassAndInstanceMethods")
|
83
|
-
serializer_klass.const_set('SerializerClassAndInstanceMethods', Module.new {})
|
84
|
-
end
|
85
|
-
if !serializer_klass.const_defined?("SerializerClassMethods")
|
86
|
-
serializer_klass.const_set('SerializerClassMethods', Module.new {})
|
87
|
-
serializer_klass::SerializerClassMethods.send(:define_method, :get_cumulatively_inherited_serializer_query_list) do |opts = {}|
|
88
|
-
if defined?(super)
|
89
|
-
return (subclass::SERIALIZER_QUERY_KEYS_CACHE + superclass.get_cumulatively_inherited_serializer_query_list).uniq
|
90
|
-
else
|
91
|
-
return subclass::SERIALIZER_QUERY_KEYS_CACHE
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
serializer_query_names = serializer_klass.public_instance_methods
|
97
|
-
|
98
|
-
serializer_query_names.each do |query_name|
|
99
|
-
serializer_name = query_name[/(?<name>.+)_query/, :name]
|
100
|
-
if serializer_name.nil?
|
101
|
-
Rails.logger.info "Serializer: #{serializer_klass.name} method #{query_name} does not end in '(.+)_query', as is expected of serializers" if Serializer.configuration.debug
|
102
|
-
next
|
103
|
-
end
|
104
|
-
# Skip if chosen to override it.
|
105
|
-
next if serializer_klass.respond_to?(serializer_name)
|
106
|
-
if serializer_name == 'serializer'
|
107
|
-
serializer_klass::SerializerClassAndInstanceMethods.send(:define_method, serializer_name) do |opts = {}|
|
108
|
-
super({json_query_override: query_name}.merge(opts))
|
109
|
-
end
|
110
|
-
else
|
111
|
-
serializer_klass::SerializerClassAndInstanceMethods.send(:define_method, serializer_name) do |opts = {}|
|
112
|
-
serializer({json_query_override: query_name}.merge(opts))
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
if serializer_query_names.any?
|
117
|
-
# Inject instance methods
|
118
|
-
subclass.send(:include, serializer_klass::SerializerClassAndInstanceMethods)
|
119
|
-
# Inject class methods
|
120
|
-
subclass.send(:extend, serializer_klass::SerializerClassAndInstanceMethods)
|
121
|
-
# Inject class methods that has queries
|
122
|
-
if Serializer.configuration.debug
|
123
|
-
Rails.logger.info "Injecting queries: #{serializer_klass.public_instance_methods} into class: #{subclass}"
|
124
|
-
end
|
125
|
-
puts "Injecting queries: #{serializer_klass.public_instance_methods} into class: #{subclass}"
|
126
|
-
subclass.send(:extend, serializer_klass)
|
127
|
-
# Injecting the Serializer Methods as a namespaced class of the rails class, so we can have
|
128
|
-
# access to the list of methods to clear their cache.
|
129
|
-
# 'Class Name + Serializer' does not work with inheritence.
|
130
|
-
subclass.const_set('SERIALIZER_QUERY_KEYS_CACHE', serializer_query_names)
|
131
|
-
# Inject class methods
|
132
|
-
subclass.send(:extend, serializer_klass::SerializerClassMethods)
|
133
|
-
|
134
|
-
# Issue with inheritting classes caching the serializer data from queries in super classes.
|
135
|
-
# Only on the rails server, not the console strangely.
|
136
|
-
if DELETE_MATCHED_SUPPORTED_CACHE_TYPES.include?(Rails.configuration.cache_store)
|
137
|
-
serializer_query_names.each do |query_name|
|
138
|
-
cache_key_prefix = /#{subclass.name}_____#{query_name}___(\d+)/
|
139
|
-
puts "Deleting cache here: Rails.cache.delete_matched(#{cache_key_prefix})"
|
140
|
-
Rails.cache.delete_matched(cache_key_prefix)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
else
|
145
|
-
Rails.logger.info "Serializer: #{serializer_klass.name} was not a Module as expected" if Serializer.configuration.debug
|
146
|
-
end
|
147
|
-
end
|
148
|
-
super(subclass)
|
149
|
-
end
|
150
|
-
|
151
|
-
# Class defined clear serializer
|
152
|
-
if DELETE_MATCHED_SUPPORTED_CACHE_TYPES.include?(Rails.configuration.cache_store)
|
153
|
-
def clear_serializer_cache
|
154
|
-
self.get_cumulatively_inherited_serializer_query_list.each do |query_name|
|
155
|
-
cache_key_prefix = /#{self.name}_____#{query_name}___(\d+)/
|
156
|
-
Rails.logger.info "Serializer: CLEARING CACHE KEY Prefix: #{cache_key_prefix}" if Serializer.configuration.debug
|
157
|
-
Rails.cache.delete_matched(cache_key_prefix)
|
158
|
-
end
|
159
|
-
return true
|
160
|
-
end
|
161
|
-
else
|
162
|
-
def clear_serializer_cache
|
163
|
-
puts "Not supported by rails cache store: #{Rails.configuration.cache_store}. Supported: #{DELETE_MATCHED_SUPPORTED_CACHE_TYPES}"
|
164
|
-
return false
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
# Can override the query, using the options. ex: {json_query_override: :tiny_children_serializer_query}
|
169
|
-
def serializer opts = {}
|
170
|
-
query = opts[:json_query_override].present? ? self.send(opts[:json_query_override], opts) : serializer_query(opts)
|
171
|
-
if Serializer.configuration.enable_includes && query[:include].present? && !opts[:skip_eager_loading]
|
172
|
-
includes(generate_includes_from_json_query(query)).as_json(query)
|
173
|
-
else
|
174
|
-
# Have to use 'all' gets stack level too deep otherwise. Not sure why.
|
175
|
-
all.as_json(query)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def as_json_associations_alias_fix options, data, opts = {}
|
180
|
-
if data
|
181
|
-
# Depth is almost purely for debugging purposes
|
182
|
-
opts[:depth] ||= 0
|
183
|
-
if options[:include].present?
|
184
|
-
options[:include].each do |include_key, include_hash|
|
185
|
-
# The includes doesn't have to have a hash attached. Skip it if it doesn't.
|
186
|
-
next if include_hash.nil?
|
187
|
-
data_key = include_key.to_s
|
188
|
-
if include_hash[:as].present?
|
189
|
-
if include_hash[:as].to_s == include_key.to_s
|
190
|
-
raise "Serializer: Cannot alias json query association to have the same as the original key; as: #{include_hash[:as].to_s}; original_key: #{include_key.to_s} on self: #{name}"
|
191
|
-
end
|
192
|
-
alias_name = include_hash[:as]
|
193
|
-
data[alias_name.to_s] = data[include_key.to_s]
|
194
|
-
data.delete(include_key.to_s)
|
195
|
-
data_key = alias_name.to_s
|
196
|
-
end
|
197
|
-
# At this point, the data could be an array of objects, with no as_json options.
|
198
|
-
if !data[data_key].is_a?(Array)
|
199
|
-
data[data_key] = as_json_associations_alias_fix(include_hash, data[data_key], {depth: opts[:depth] + 1})
|
200
|
-
else
|
201
|
-
data[data_key].each_with_index do |value,i|
|
202
|
-
data[data_key][i] = as_json_associations_alias_fix(include_hash, value, {depth: opts[:depth] + 1})
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
return data
|
209
|
-
end
|
210
|
-
|
211
|
-
def generate_includes_from_json_query options = {}, klass = nil
|
212
|
-
query_filter = {}
|
213
|
-
klass = self if klass.nil?
|
214
|
-
if options[:include].present? && !options[:skip_eager_loading]
|
215
|
-
options[:include].each do |include_key, include_hash|
|
216
|
-
next if include_hash[:skip_eager_loading] == true
|
217
|
-
# Will 'next' if there is a scope that takes arguments, an instance-dependent scope.
|
218
|
-
# Can't eager load when assocation has a instance condition for it's associative scope.
|
219
|
-
# Might not be a real assocation
|
220
|
-
next if klass.reflect_on_association(include_key).nil?
|
221
|
-
next if klass.reflect_on_association(include_key).scope&.arity&.nonzero?
|
222
|
-
query_filter[include_key] = {}
|
223
|
-
next if include_hash.none?
|
224
|
-
query_filter[include_key] = generate_includes_from_json_query(include_hash, klass.reflect_on_association(include_key).klass)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
# Does not include data, just eager-loads. Useful when methods need assocations, but you don't need association data.
|
228
|
-
if options[:eager_include].present?
|
229
|
-
options[:eager_include].each do |include_key|
|
230
|
-
# Will 'next' if there is a scope that takes arguments, an instance-dependent scope.
|
231
|
-
# Can't eager load when assocation has a instance condition for it's associative scope.
|
232
|
-
# Might not be a real assocation
|
233
|
-
next if klass.reflect_on_association(include_key).nil?
|
234
|
-
next if klass.reflect_on_association(include_key).scope&.arity&.nonzero?
|
235
|
-
query_filter[include_key] ||= {}
|
236
|
-
end
|
237
|
-
end
|
238
|
-
return query_filter
|
239
|
-
end
|
240
|
-
# END MODEL CLASS METHODS
|
241
|
-
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|