grape-entity-preloader 0.1.0 → 0.3.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: 3d32cc4a359717abe3519c7f8bee48d9e35029d1348057a7fa35b043594dd1b5
4
- data.tar.gz: 9ef42ce05db679a5cf7830aeaae698b1557452957648e668ced0ced0cd1e4a3a
3
+ metadata.gz: 4435d853f0ac2438cbd9def7d195a78e4ce66dcfc0db4015b29f20c5102846b6
4
+ data.tar.gz: 2bde5dbb73a91201040bc0e21da30507638c1b61e164e494a6187dacc1ab328d
5
5
  SHA512:
6
- metadata.gz: e9101088f6433f7372ad46b061c34341553259a91a3f903ec1d2dde1112bd2e2d944aec61fcb4ba1ac5ae5828719b3d9eb9dfda88134351e739982e8a8e03149
7
- data.tar.gz: 6d46c749603a41caff0bec514091adc6b630d521c2d0b84aa62f879f76058b4d81185a493f1684eb5f54548290d702462a946cd1c3617af420fd469f16bb023a
6
+ metadata.gz: 36b9c7316b3cb852024039a2db9ffe0c55215f49c60614b49c95a23a1bf307432b8e564c8c09cd3b56b71a4ed5f212e5fbd756e87675901407acb8acd5a8b642
7
+ data.tar.gz: 8f9c9b1ed336765001069d34ab27e7b80e5a94d6a829ffd276ff501785ed15d4a8f43d9cdf762c6a79603487e16ddff00669e0a2222833c091e8ff8ebd7a6532
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2025-10-14 UTC
4
+
5
+ - ⚠️ [Broken] Remove `:grape_entity_preloader` option functionality, please use `Grape::Entity::Preloader.with_enable` or `Grape::Entity::Preloader.with_disable` instead.
6
+
3
7
  ## [0.1.0] - 2025-10-12 UTC
4
8
 
5
9
  - Initial release
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Grape::Entity::Preloader
2
2
 
3
+ [![Ruby](https://github.com/OuYangJinTing/grape-entity-preloader/actions/workflows/main.yml/badge.svg)](https://github.com/OuYangJinTing/grape-entity-preloader/actions/workflows/main.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/grape-entity-preloader.svg?icon=si%3Arubygems&icon_color=%23ff0000)](https://badge.fury.io/rb/grape-entity-preloader)
5
+
3
6
  Grape::Entity::Preloader allows preload associations and callbacks for avoiding N+1 operations in Grape::Entity.
4
7
 
5
8
  ## Installation
@@ -30,21 +33,6 @@ Grape::Entity::Preloader.enabled!
30
33
  #### Local Activation and Deactivation
31
34
 
32
35
  You can control preloading for specific `represent` calls.
33
-
34
- ##### 1. Using options
35
-
36
- Pass `grape_entity_preloader: :enabled` or `grape_entity_preloader: :disabled` to the options hash. This overrides the global setting.
37
-
38
- ```ruby
39
- # Locally enable
40
- MyEntity.represent(users, grape_entity_preloader: :enabled)
41
-
42
- # Locally disable
43
- MyEntity.represent(users, grape_entity_preloader: :disabled)
44
- ```
45
-
46
- ##### 2. Using a block
47
-
48
36
  For a specific block of code, you can use `with_enable` or `with_disable`. This is useful in contexts like API endpoints or middlewares.
49
37
 
50
38
  ```ruby
@@ -10,11 +10,8 @@ module Grape
10
10
  def represent(objects, options = {})
11
11
  options = Grape::Entity::Options.new(options) unless options.is_a?(Grape::Entity::Options)
12
12
 
13
- options[:grape_entity_preloader] ||= Preloader.enabled? ? :enabled : :disabled
14
- Preloader.new(root_exposures, objects, options).call if options[:grape_entity_preloader] == :enabled
15
- options[:grape_entity_preloader] = :finished
16
-
17
- super(objects, options)
13
+ Preloader.new(root_exposures, objects, options).call if Preloader.enabled?
14
+ Preloader.with_disable { super(objects, options) }
18
15
  end
19
16
  end
20
17
  end
@@ -3,7 +3,7 @@
3
3
  module Grape
4
4
  class Entity
5
5
  class Preloader
6
- VERSION = '0.1.0'
6
+ VERSION = '0.3.0'
7
7
  end
8
8
  end
9
9
  end
@@ -26,18 +26,20 @@ module Grape
26
26
  end
27
27
  end
28
28
 
29
- def self.with_enable
29
+ def self.with_enable # rubocop:disable Metrics/MethodLength
30
30
  return yield if enabled?
31
31
 
32
- old_value = ActiveSupport::IsolatedExecutionState[:grape_entity_preloader]
33
- ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = true
32
+ begin
33
+ old_value = ActiveSupport::IsolatedExecutionState[:grape_entity_preloader]
34
+ ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = true
34
35
 
35
- yield
36
-
37
- if old_value.nil?
38
- ActiveSupport::IsolatedExecutionState.delete(:grape_entity_preloader)
39
- else
40
- ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = old_value
36
+ yield
37
+ ensure
38
+ if old_value.nil?
39
+ ActiveSupport::IsolatedExecutionState.delete(:grape_entity_preloader)
40
+ else
41
+ ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = old_value
42
+ end
41
43
  end
42
44
  end
43
45
 
@@ -49,18 +51,20 @@ module Grape
49
51
  !enabled?
50
52
  end
51
53
 
52
- def self.with_disable
54
+ def self.with_disable # rubocop:disable Metrics/MethodLength
53
55
  return yield if disabled?
54
56
 
55
- old_value = ActiveSupport::IsolatedExecutionState[:grape_entity_preloader]
56
- ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = false
57
+ begin
58
+ old_value = ActiveSupport::IsolatedExecutionState[:grape_entity_preloader]
59
+ ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = false
57
60
 
58
- yield
59
-
60
- if old_value.nil?
61
- ActiveSupport::IsolatedExecutionState.delete(:grape_entity_preloader)
62
- else
63
- ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = old_value
61
+ yield
62
+ ensure
63
+ if old_value.nil?
64
+ ActiveSupport::IsolatedExecutionState.delete(:grape_entity_preloader)
65
+ else
66
+ ActiveSupport::IsolatedExecutionState[:grape_entity_preloader] = old_value
67
+ end
64
68
  end
65
69
  end
66
70
 
@@ -4,4 +4,32 @@ RSpec.describe Grape::Entity::Preloader do
4
4
  it 'has a version number' do
5
5
  expect(Grape::Entity::Preloader::VERSION).not_to be_nil
6
6
  end
7
+
8
+ describe '.with_enable' do
9
+ it 'returns the value of the block' do
10
+ result = described_class.with_enable { 42 }
11
+ expect(result).to eq(42)
12
+ end
13
+
14
+ it 'returns the value of the block when already enabled' do
15
+ described_class.enabled!
16
+ result = described_class.with_enable { 'hello' }
17
+ expect(result).to eq('hello')
18
+ ensure
19
+ described_class.disabled!
20
+ end
21
+ end
22
+
23
+ describe '.with_disable' do
24
+ it 'returns the value of the block' do
25
+ result = described_class.with_disable { 42 }
26
+ expect(result).to eq(42)
27
+ end
28
+
29
+ it 'returns the value of the block when already disabled' do
30
+ described_class.disabled!
31
+ result = described_class.with_disable { 'hello' }
32
+ expect(result).to eq('hello')
33
+ end
34
+ end
7
35
  end
@@ -105,7 +105,7 @@ RSpec.describe 'N+1 operation' do # rubocop:disable RSpec/DescribeClass
105
105
  User::Entity.represent(
106
106
  users,
107
107
  serializable: true,
108
- only: [books_by_association: %i[tags_by_association tags_by_callback]]
108
+ only: [{ books_by_association: %i[tags_by_association tags_by_callback] }]
109
109
  )
110
110
  end.to make_database_queries(count: 3)
111
111
  .and make_database_queries(count: 1, matching: /user_books_by_association/)
@@ -121,7 +121,7 @@ RSpec.describe 'N+1 operation' do # rubocop:disable RSpec/DescribeClass
121
121
  }
122
122
 
123
123
  expect do
124
- User::Entity.represent(users, options.dup)
124
+ User::Entity.represent(users, options)
125
125
  end.to make_database_queries(count: 1)
126
126
  .and make_database_queries(count: 1, matching: /user_books_by_association/)
127
127
 
@@ -129,7 +129,7 @@ RSpec.describe 'N+1 operation' do # rubocop:disable RSpec/DescribeClass
129
129
 
130
130
  options[:only] << { books_by_association: [:tags_by_association] }
131
131
  expect do
132
- User::Entity.represent(users, options.dup)
132
+ User::Entity.represent(users, options)
133
133
  end.to make_database_queries(count: 2)
134
134
  .and make_database_queries(count: 1, matching: /user_books_by_association/)
135
135
  .and make_database_queries(count: 1, matching: /book_tags_by_association/)
@@ -149,7 +149,7 @@ RSpec.describe 'N+1 operation' do # rubocop:disable RSpec/DescribeClass
149
149
  User::Entity.represent(
150
150
  users,
151
151
  serializable: true,
152
- only: [books_by_callback: %i[tags_by_association tags_by_callback]]
152
+ only: [{ books_by_callback: %i[tags_by_association tags_by_callback] }]
153
153
  )
154
154
  end.to make_database_queries(count: 3)
155
155
  .and make_database_queries(count: 1, matching: /books_by_callback/)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-entity-preloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OuYangJinTing