Skip to content

Commit f80603e

Browse files
committed
refactor: avoid using global variables for shared data
1 parent 4d2468d commit f80603e

File tree

3 files changed

+17
-100
lines changed

3 files changed

+17
-100
lines changed

lib/inertia_rails/controller.rb

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,16 @@ module Controller
55
extend ActiveSupport::Concern
66

77
included do
8-
before_action do
9-
# :inertia_errors are deleted from the session by the middleware
10-
InertiaRails.share(errors: session[:inertia_errors]) if session[:inertia_errors].present?
11-
end
12-
138
after_action do
149
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
1510
end
1611
end
1712

1813
module ClassMethods
19-
def inertia_share(**args, &block)
20-
before_action do
21-
InertiaRails.share(**args) if args
22-
InertiaRails.share_block(block) if block
23-
end
14+
def inertia_share(**attrs, &block)
15+
@inertia_shared_data ||= []
16+
@inertia_shared_data << attrs unless attrs.empty?
17+
@inertia_shared_data << block if block
2418
end
2519

2620
def inertia_config(**attrs)
@@ -44,6 +38,10 @@ def _inertia_configuration
4438
config = superclass.try(:_inertia_configuration) || ::InertiaRails.configuration
4539
@inertia_configuration ? config.merge(@inertia_configuration) : config
4640
end
41+
42+
def _inertia_shared_data
43+
[*superclass.try(:_inertia_shared_data), *@inertia_shared_data]
44+
end
4745
end
4846

4947
def default_render
@@ -80,7 +78,15 @@ def inertia_configuration
8078
end
8179

8280
def inertia_shared_data
83-
::InertiaRails.shared_data(self)
81+
initial_data = session[:inertia_errors].present? ? {errors: session[:inertia_errors]} : {}
82+
83+
self.class._inertia_shared_data.filter_map { |shared_data|
84+
if shared_data.respond_to?(:call)
85+
instance_exec(&shared_data)
86+
else
87+
shared_data
88+
end
89+
}.reduce(initial_data, &:merge)
8490
end
8591

8692
def inertia_location(url)

lib/inertia_rails/inertia_rails.rb

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
require 'inertia_rails/configuration'
55

66
module InertiaRails
7-
thread_mattr_accessor :threadsafe_shared_plain_data
8-
thread_mattr_accessor :threadsafe_shared_blocks
9-
107
CONFIGURATION = Configuration.default
118

129
def self.configure
@@ -17,50 +14,10 @@ def self.configuration
1714
CONFIGURATION
1815
end
1916

20-
# "Getters"
21-
def self.shared_data(controller)
22-
shared_plain_data.
23-
merge!(evaluated_blocks(controller, shared_blocks))
24-
end
25-
26-
# "Setters"
27-
def self.share(**args)
28-
self.shared_plain_data = self.shared_plain_data.merge(args)
29-
end
30-
31-
def self.share_block(block)
32-
self.shared_blocks = self.shared_blocks + [block]
33-
end
34-
3517
def self.reset!
36-
self.shared_plain_data = {}
37-
self.shared_blocks = []
3818
end
3919

4020
def self.lazy(value = nil, &block)
4121
InertiaRails::Lazy.new(value, &block)
4222
end
43-
44-
private
45-
46-
# Getters and setters to provide default values for the threadsafe attributes
47-
def self.shared_plain_data
48-
self.threadsafe_shared_plain_data || {}
49-
end
50-
51-
def self.shared_plain_data=(val)
52-
self.threadsafe_shared_plain_data = val
53-
end
54-
55-
def self.shared_blocks
56-
self.threadsafe_shared_blocks || []
57-
end
58-
59-
def self.shared_blocks=(val)
60-
self.threadsafe_shared_blocks = val
61-
end
62-
63-
def self.evaluated_blocks(controller, blocks)
64-
blocks.flat_map { |block| controller.instance_exec(&block) }.reduce(&:merge) || {}
65-
end
6623
end

spec/inertia/sharing_spec.rb

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -54,52 +54,6 @@
5454
it { is_expected.to eq props.merge({ errors: errors }) }
5555
end
5656

57-
context 'multithreaded intertia share' do
58-
let(:props) { { name: 'Michael', has_goat_status: true } }
59-
it 'is expected to render props even when another thread shares Inertia data' do
60-
start_thread1 = false
61-
start_thread2 = false
62-
63-
thread1 = Thread.new do
64-
sleep 0.1 until start_thread1
65-
66-
get share_multithreaded_path, headers: {'X-Inertia' => true}
67-
expect(subject).to eq props
68-
end
69-
70-
thread2 = Thread.new do
71-
sleep 0.1 until start_thread2
72-
73-
# Would prefer to make this a second get request, but RSpec will overwrite
74-
# the @response variable if another request is made in the second thread.
75-
# This simulates the relevant effects of another call to a different
76-
# controller with different values for inertia_share
77-
InertiaRails.reset!
78-
InertiaRails.share(name: 'Brian', has_goat_status: false)
79-
end
80-
81-
# Thread 1 starts. The controller method runs inertia_share, then sleeps.
82-
# Thread 2 then modifies the shared inertia data before Thread 1 stops sleeping
83-
start_thread1 = true
84-
sleep 0.5
85-
start_thread2 = true
86-
87-
# Make sure that both threads finish before the block returns
88-
thread1.join
89-
thread2.join
90-
end
91-
92-
it 'is expected not to leak shared data across requests' do
93-
begin
94-
get share_multithreaded_error_path, headers: {'X-Inertia' => true}
95-
rescue Exception
96-
end
97-
98-
expect(InertiaRails.shared_plain_data).to be_empty
99-
expect(InertiaRails.shared_blocks).to be_empty
100-
end
101-
end
102-
10357
describe 'deep or shallow merging shared data' do
10458
context 'with default settings (shallow merge)' do
10559
describe 'shallow merging by default' do

0 commit comments

Comments
 (0)