plucker_serializer 0.2.2 → 0.5.0

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