Skip to content

Commit 5fb2df2

Browse files
committed
refactor: cache resolved shared data and config in controller classes
Shared data is now frozen to prevent Also, match the method names for instance variables. Updated a test that used to call `inertia_share` inside a `before_action` as that seems like something a user should never do.
1 parent f8a6663 commit 5fb2df2

File tree

6 files changed

+49
-19
lines changed

6 files changed

+49
-19
lines changed

lib/inertia_rails/configuration.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,20 @@ def bind_controller(controller)
3232
Configuration.new(**@options, controller: controller)
3333
end
3434

35+
def freeze
36+
@options.freeze
37+
super
38+
end
39+
3540
def to_h
3641
@options.to_h
3742
end
3843

44+
def merge!(config)
45+
@options.merge!(config.options)
46+
self
47+
end
48+
3949
def merge(config)
4050
Configuration.new(**@options.merge(config.options))
4151
end

lib/inertia_rails/controller.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ module Controller
1515

1616
module ClassMethods
1717
def inertia_share(**attrs, &block)
18-
@inertia_shared_data ||= []
19-
@inertia_shared_data << attrs unless attrs.empty?
20-
@inertia_shared_data << block if block
18+
@inertia_share ||= []
19+
@inertia_share << attrs.freeze unless attrs.empty?
20+
@inertia_share << block if block
2121
end
2222

2323
def inertia_config(**attrs)
2424
config = InertiaRails::Configuration.new(**attrs)
2525

26-
if @inertia_configuration
27-
@inertia_configuration.merge!(config)
26+
if @inertia_config
27+
@inertia_config.merge!(config)
2828
else
29-
@inertia_configuration = config
29+
@inertia_config = config
3030
end
3131
end
3232

@@ -38,12 +38,14 @@ def use_inertia_instance_props
3838
end
3939

4040
def _inertia_configuration
41-
config = superclass.try(:_inertia_configuration) || ::InertiaRails.configuration
42-
@inertia_configuration ? config.merge(@inertia_configuration) : config
41+
@_inertia_configuration ||= begin
42+
config = superclass.try(:_inertia_configuration) || ::InertiaRails.configuration
43+
@inertia_config ? config.merge(@inertia_config).freeze : config
44+
end
4345
end
4446

4547
def _inertia_shared_data
46-
[*superclass.try(:_inertia_shared_data), *@inertia_shared_data]
48+
@_inertia_shared_data ||= [*superclass.try(:_inertia_shared_data), *@inertia_share].freeze
4749
end
4850
end
4951

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
class InertiaConditionalSharingController < ApplicationController
2-
before_action :conditionally_share_props, only: [:show]
32
inertia_share normal_shared_prop: 1
43

4+
inertia_share do
5+
{conditionally_shared_show_prop: 1} if action_name == "show"
6+
end
7+
58
def index
69
render inertia: 'EmptyTestComponent', props: {
710
index_only_prop: 1,
@@ -13,10 +16,4 @@ def show
1316
show_only_prop: 1,
1417
}
1518
end
16-
17-
protected
18-
19-
def conditionally_share_props
20-
self.class.inertia_share conditionally_shared_show_prop: 1
21-
end
2219
end

spec/dummy/app/controllers/inertia_config_test_controller.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ class InertiaConfigTestController < ApplicationController
77
version: "2.0",
88
)
99

10+
# Test that modules included in the same class can also call it.
11+
inertia_config(
12+
version: "2.0",
13+
)
14+
1015
def configuration
1116
render json: inertia_configuration.to_h
1217
end

spec/inertia/conditional_sharing_spec.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
RSpec.describe "conditionally shared data in a controller", type: :request do
2-
context "when there is a before_action inside a inertia_share" do
3-
it "does leak data between requests" do
2+
context "when there is conditional data inside inertia_share" do
3+
it "does not leak data between requests" do
44
get conditional_share_index_path, headers: {'X-Inertia' => true}
55
expect(JSON.parse(response.body)['props'].deep_symbolize_keys).to eq({
66
index_only_prop: 1,
@@ -22,7 +22,6 @@
2222
expect(JSON.parse(response.body)['props'].deep_symbolize_keys).to eq({
2323
index_only_prop: 1,
2424
normal_shared_prop: 1,
25-
conditionally_shared_show_prop: 1,
2625
})
2726
end
2827
end

spec/inertia/configuration_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
RSpec.describe 'Inertia configuration', type: :request do
22
after { reset_config! }
33

4+
describe "InertiaRails::Configuration" do
5+
it "does not allow to modify options after frozen" do
6+
config = InertiaRails::Configuration.default
7+
config.ssr_enabled = true
8+
expect(config.ssr_enabled).to eq true
9+
10+
config.freeze
11+
expect { config.ssr_enabled = false }.to raise_error(FrozenError)
12+
expect { config.merge!(InertiaRails::Configuration.default) }.to raise_error(FrozenError)
13+
14+
expect {
15+
merged_config = config.merge(InertiaRails::Configuration.default)
16+
expect(merged_config.ssr_enabled).to eq false
17+
}.not_to raise_error
18+
end
19+
end
20+
421
describe 'inertia_config' do
522
it 'overrides the global values' do
623
get configuration_path

0 commit comments

Comments
 (0)