plucker_serializer 0.2.2 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b8f9afc9f1301b0b3d66270d02332a3c561f154e812c14473d82b26455da90e
4
- data.tar.gz: 9081e6e37b2ae439c167774d58b35702e4bc6d8ba5daea474496feae8bcd7835
3
+ metadata.gz: 3b74f3d1f2fee4bfa2fd0fc3e6968f35f6d1bbe852b69c6fda56ad63bdbe8ada
4
+ data.tar.gz: c9daa990c9d467958e6f30dd2faba3a69aa81dfa0708a6289243026504f88351
5
5
  SHA512:
6
- metadata.gz: 831adf15e780f90a1ee9f64811f7a8bf0a684e929a2030884daac8496fafb645473c4d4633d061463f4ca99afb3134bed70b5d22bc691d0103a2f831bf23af68
7
- data.tar.gz: 03fc6353497d3abb9668fe4c36e8d68cade203310e2b2bd20afaf21baa09ad6caf9f16de434b30aec6c168573525a6c5e7d05daa15f0d570402d26352a412fbb
6
+ metadata.gz: f051ad0a434f02690092cdeb7481db0fc606b780574d8109251746f99b3f1888842c906231321f82ba896e9615939461a93ad95245082086235cb670fc27710b
7
+ data.tar.gz: b05c2e4c4f327a32c0c9faeae82fc017265f316e41f5f111a709577801862a70d481f7545b226b8cb848a8a83d705702a963851e9582ba2fbc72ec670ba3ccb3
@@ -1,5 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
  module Plucker
3
- class Attribute < Plucker::Field
3
+ class Attribute
4
+ attr_reader :name, :block, :condition
5
+
6
+ def initialize(name, options = {}, block)
7
+ @name = name
8
+ @block = block
9
+ @condition = options[:if]
10
+ end
11
+
12
+ def value(serializer)
13
+ block_value = instance_exec(serializer.object, &@block) if @block
14
+ if @block && block_value != :nil
15
+ block_value
16
+ else
17
+ if serializer.respond_to?(@name)
18
+ serializer.send(@name)
19
+ else
20
+ serializer.object.send(@name)
21
+ end
22
+ end
23
+ end
24
+
25
+ def is_pluckable?
26
+ @block.blank?
27
+ end
28
+
29
+ def should_include?(serializer)
30
+ case @condition
31
+ when nil
32
+ true
33
+ when Symbol
34
+ serializer.public_send(@condition)
35
+ when String
36
+ serializer.instance_eval(@condition)
37
+ when Proc
38
+ if @condition.arity.zero?
39
+ serializer.instance_exec(&@condition)
40
+ else
41
+ serializer.instance_exec(serializer, &@condition)
42
+ end
43
+ else
44
+ nil
45
+ end
46
+ end
4
47
  end
5
48
  end
data/lib/plucker/base.rb CHANGED
@@ -4,6 +4,7 @@ require_relative 'descriptor'
4
4
  require_relative 'has_many'
5
5
  require_relative 'belongs_to'
6
6
  require_relative 'has_one'
7
+ require "oj"
7
8
  require 'active_support/all'
8
9
 
9
10
  module Plucker
@@ -26,9 +27,9 @@ module Plucker
26
27
  self.object = object
27
28
  end
28
29
 
29
- def serializable_hash
30
- if self.class.cache_enabled?
31
- fetch do
30
+ def serializable_hash(use_cache: true)
31
+ if use_cache && self.class.cache_enabled?
32
+ fetch(adapter: :hash) do
32
33
  get_hash
33
34
  end
34
35
  else
@@ -38,27 +39,35 @@ module Plucker
38
39
  alias to_hash serializable_hash
39
40
  alias to_h serializable_hash
40
41
 
41
- def get_hash
42
- attributes_hash.merge! associations_hash
42
+ def as_json(options = nil)
43
+ serializable_hash
43
44
  end
44
45
 
45
- def as_json(options = nil)
46
- to_h.as_json(options)
46
+ def to_json(options = {}, use_cache: true)
47
+ if use_cache && self.class.cache_enabled?
48
+ fetch(adapter: :json) do
49
+ Oj.dump(get_hash, mode: :rails)
50
+ end
51
+ else
52
+ Oj.dump(get_hash, mode: :rails)
53
+ end
54
+ end
55
+
56
+ def get_hash
57
+ attributes_hash.merge! associations_hash
47
58
  end
48
59
 
49
60
  def associations_hash
50
- hash = {}
51
- self.class._descriptor._relationships.each do |(key, relationship)|
52
- next if relationship.excluded?(self)
53
- hash[key] = relationship.value(self)
61
+ self.class._descriptor._relationships.each_with_object({}) do |(key, relationship), hash|
62
+ next if !relationship.should_include?(self)
63
+ hash[key.to_s] = relationship.value(self)
54
64
  end
55
- hash
56
65
  end
57
66
 
58
67
  def attributes_hash
59
68
  self.class._descriptor._attributes.each_with_object({}) do |(key, attr), hash|
60
- next if attr.excluded?(self)
61
- hash[key] = attr.value(self)
69
+ next if !attr.should_include?(self)
70
+ hash[key.to_s] = attr.value(self)
62
71
  end
63
72
  end
64
73
 
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
  require_relative 'concerns/caching'
3
+ require "oj"
4
+ require "pluck_all"
3
5
 
4
6
  module Plucker
5
7
  class Collection
6
8
  include Enumerable
7
9
  include Caching
8
10
 
9
- attr_reader :objects, :serializer_class, :options
11
+ attr_reader :objects, :cache_type, :serializer_class, :options
10
12
 
11
13
  def initialize(objects, options = {})
12
14
  @objects = objects
13
15
  @options = options
16
+ @cache_type = options[:cache] == :multi ? :multi : :collection
14
17
  @serializer_class = get_serialized_model(objects)
15
18
  end
16
19
 
@@ -21,23 +24,15 @@ module Plucker
21
24
  end.compact
22
25
  else
23
26
  if serializer_class.cache_enabled?
24
- fetch do
25
- if serializer_class.is_pluckable?
26
- associated_hash
27
- else
28
- objects.map do |object|
29
- serializer_class.new(object).serializable_hash
30
- end.compact
27
+ if @cache_type == :collection
28
+ fetch(adapter: :hash) do
29
+ get_hash(use_cache: false)
31
30
  end
31
+ elsif @cache_type == :multi
32
+ get_hash(use_cache: true)
32
33
  end
33
34
  else
34
- if serializer_class.is_pluckable?
35
- associated_hash
36
- else
37
- objects.map do |object|
38
- serializer_class.new(object).serializable_hash
39
- end.compact
40
- end
35
+ get_hash(use_cache: false)
41
36
  end
42
37
  end
43
38
  end
@@ -45,7 +40,41 @@ module Plucker
45
40
  alias to_h serializable_hash
46
41
 
47
42
  def as_json(options = nil)
48
- to_h.as_json(options)
43
+ serializable_hash
44
+ end
45
+
46
+ def to_json(options = {})
47
+ if serializer_class.cache_enabled?
48
+ if @cache_type == :collection
49
+ fetch(adapter: :json) do
50
+ Oj.dump(get_collection_json(use_cache: false), mode: :rails)
51
+ end
52
+ elsif @cache_type == :multi
53
+ Oj.dump(get_collection_json(use_cache: true), mode: :rails)
54
+ end
55
+ else
56
+ Oj.dump(get_collection_json(use_cache: false), mode: :rails)
57
+ end
58
+ end
59
+
60
+ def get_collection_json(use_cache: false)
61
+ if serializer_class.is_pluckable?
62
+ associated_hash
63
+ else
64
+ objects.map do |object|
65
+ Oj.load(serializer_class.new(object).to_json(use_cache: use_cache))
66
+ end
67
+ end
68
+ end
69
+
70
+ def get_hash(use_cache: false)
71
+ if serializer_class.is_pluckable?
72
+ associated_hash
73
+ else
74
+ objects.map do |object|
75
+ serializer_class.new(object).serializable_hash(use_cache: use_cache)
76
+ end.compact
77
+ end
49
78
  end
50
79
 
51
80
  def cache_version
@@ -53,9 +82,8 @@ module Plucker
53
82
  @cache_version = objects.cache_version
54
83
  end
55
84
 
56
- def cache_key
57
- return @cache_key if defined?(@cache_key)
58
- @cache_key = objects.cache_key + '/' + serializer_class._cache_digest
85
+ def cache_key(adapter: :json)
86
+ objects.cache_key + '/' + serializer_class._cache_digest + "/" + adapter.to_s
59
87
  end
60
88
 
61
89
  private
@@ -63,9 +91,9 @@ module Plucker
63
91
  pluck_to_hash(objects, serializer_class.pluckable_columns.to_a)
64
92
  end
65
93
 
66
- def pluck_to_hash(object, attrs)
67
- namespaced_attrs = attrs.map { |attr| object.model.table_name.to_s + "." + attr.to_s }
68
- object.pluck(Arel.sql(namespaced_attrs.join(','))).map { |el| attrs.zip(el).to_h }
94
+ def pluck_to_hash(objects, attrs)
95
+ namespaced_attrs = attrs.map { |attr| objects.model.table_name.to_s + "." + attr.to_s }
96
+ objects.pluck_all(namespaced_attrs.join(','))
69
97
  end
70
98
 
71
99
  def get_serialized_model(objects)
@@ -30,9 +30,9 @@ module Plucker
30
30
  end
31
31
  end
32
32
 
33
- def fetch
33
+ def fetch(adapter: :json)
34
34
  if serializer_class.cache_enabled?
35
- serializer_class._cache_store.fetch(cache_key, version: cache_version, options: serializer_class._cache_options) do
35
+ serializer_class._cache_store.fetch(cache_key(adapter: adapter), version: cache_version, options: serializer_class._cache_options) do
36
36
  yield
37
37
  end
38
38
  else
@@ -45,9 +45,8 @@ module Plucker
45
45
  @cache_version = object.cache_version
46
46
  end
47
47
 
48
- def cache_key
49
- return @cache_key if defined?(@cache_key)
50
- @cache_key = object.cache_key + "/" + serializer_class._cache_digest
48
+ def cache_key(adapter: :json)
49
+ object.cache_key + "/" + serializer_class._cache_digest + "/" + adapter.to_s
51
50
  end
52
51
 
53
52
  def serializer_class
@@ -7,12 +7,12 @@ module Plucker
7
7
  self._serialized_model = get_serialized_model(serializer_class)
8
8
  self._attributes = {}
9
9
  self._relationships = {}
10
- self._pluckable_columns = Set.new([:updated_at])
10
+ self._pluckable_columns = Set.new
11
11
  self._is_pluckable = true
12
12
  end
13
13
 
14
14
  def is_pluckable?
15
- self._is_pluckable && !self._relationships.present?
15
+ self._is_pluckable
16
16
  end
17
17
 
18
18
  def add_attribute(key, attr)
@@ -1,15 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
  require_relative 'collection'
3
- require_relative "field"
4
3
 
5
4
  module Plucker
6
- class Relationship < Plucker::Field
5
+ class Relationship
6
+ attr_reader :name, :block, :options, :condition
7
+
8
+ def initialize(name, options = {}, block)
9
+ @name = name
10
+ @block = block
11
+ @options = options
12
+ @condition = options[:if]
13
+ end
14
+
15
+ def should_include?(serializer)
16
+ case @condition
17
+ when nil
18
+ true
19
+ when Symbol
20
+ serializer.public_send(@condition)
21
+ when String
22
+ serializer.instance_eval(@condition)
23
+ when Proc
24
+ if @condition.arity.zero?
25
+ serializer.instance_exec(&@condition)
26
+ else
27
+ serializer.instance_exec(serializer, &@condition)
28
+ end
29
+ else
30
+ nil
31
+ end
32
+ end
33
+
7
34
  def associated_object(serializer)
8
- block_value = instance_exec(serializer.object, &block) if block
9
- if block && block_value != :nil
35
+ block_value = instance_exec(serializer.object, &@block) if @block
36
+ if @block && block_value != :nil
10
37
  block_value
11
38
  else
12
- serializer.object.send(name)
39
+ serializer.object.send(@name)
13
40
  end
14
41
  end
15
42
 
@@ -19,15 +46,15 @@ module Plucker
19
46
 
20
47
  private
21
48
  def relationship_serializer(serializer, relationship_object=nil)
22
- if self.options[:serializer].blank?
49
+ if @options[:serializer].blank?
23
50
  if relationship_object.present?
24
51
  association_class = relationship_object.class.name
25
52
  else
26
- association_class = serializer.object.class.reflect_on_association(self.name.to_sym).class_name
53
+ association_class = serializer.object.class.reflect_on_association(@name.to_sym).class_name
27
54
  end
28
55
  "#{association_class.demodulize.camelize}Serializer".constantize
29
56
  else
30
- self.options[:serializer]
57
+ @options[:serializer]
31
58
  end
32
59
  end
33
60
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Plucker
3
- VERSION = "0.2.2"
3
+ VERSION = "0.5.0"
4
4
  end
@@ -7,7 +7,6 @@ require "plucker/relationship"
7
7
  require "plucker/belongs_to"
8
8
  require "plucker/has_one"
9
9
  require "plucker/has_many"
10
- require "plucker/field"
11
10
  require "plucker/descriptor"
12
11
  require "plucker/concerns/caching"
13
12
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plucker_serializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henry Boisgibault
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-01 00:00:00.000000000 Z
11
+ date: 2022-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pluck_all
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  description: A blazing fast JSON serializer for ActiveRecord & Ruby objects
28
56
  email: henry@logora.fr
29
57
  executables: []
@@ -37,7 +65,6 @@ files:
37
65
  - lib/plucker/concerns/caching.rb
38
66
  - lib/plucker/configuration.rb
39
67
  - lib/plucker/descriptor.rb
40
- - lib/plucker/field.rb
41
68
  - lib/plucker/has_many.rb
42
69
  - lib/plucker/has_one.rb
43
70
  - lib/plucker/relationship.rb
data/lib/plucker/field.rb DELETED
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
- module Plucker
3
- Field = Struct.new(:name, :options, :block) do
4
- def initialize(*)
5
- super
6
- validate_condition!
7
- end
8
-
9
- def value(serializer)
10
- block_value = instance_exec(serializer.object, &block) if block
11
- if block && block_value != :nil
12
- block_value
13
- else
14
- if serializer.respond_to?(name)
15
- serializer.send(name)
16
- else
17
- serializer.object.send(name)
18
- end
19
- end
20
- end
21
-
22
- def is_pluckable?
23
- block.blank?
24
- end
25
-
26
- def excluded?(serializer)
27
- case condition_type
28
- when :if
29
- !evaluate_condition(serializer)
30
- when :unless
31
- evaluate_condition(serializer)
32
- else
33
- false
34
- end
35
- end
36
-
37
- private
38
- def validate_condition!
39
- return if condition_type == :none
40
-
41
- case condition
42
- when Symbol, String, Proc
43
- # noop
44
- else
45
- fail TypeError, "#{condition_type.inspect} should be a Symbol, String or Proc"
46
- end
47
- end
48
-
49
- def evaluate_condition(serializer)
50
- case condition
51
- when Symbol
52
- serializer.public_send(condition)
53
- when String
54
- serializer.instance_eval(condition)
55
- when Proc
56
- if condition.arity.zero?
57
- serializer.instance_exec(&condition)
58
- else
59
- serializer.instance_exec(serializer, &condition)
60
- end
61
- else
62
- nil
63
- end
64
- end
65
-
66
- def condition_type
67
- @condition_type ||=
68
- if options.key?(:if)
69
- :if
70
- elsif options.key?(:unless)
71
- :unless
72
- else
73
- :none
74
- end
75
- end
76
-
77
- def condition
78
- options[condition_type]
79
- end
80
- end
81
- end