Skip to content

Commit c4c5d6f

Browse files
committed
Fix scroll and deferred props from shared data by merging shared data in renderer initializer
1 parent 99774c8 commit c4c5d6f

File tree

4 files changed

+77
-8
lines changed

4 files changed

+77
-8
lines changed

lib/inertia_rails/renderer.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@ def initialize(component, controller, request, response, render_method, **option
2424

2525
@controller = controller
2626
@configuration = controller.__send__(:inertia_configuration)
27-
@component = resolve_component(component)
2827
@request = request
2928
@response = response
3029
@render_method = render_method
31-
@props = options.fetch(:props, component.is_a?(Hash) ? component : controller.__send__(:inertia_view_assigns))
3230
@view_data = options.fetch(:view_data, {})
33-
@deep_merge = options.fetch(:deep_merge, configuration.deep_merge_shared_data)
3431
@encrypt_history = options.fetch(:encrypt_history, configuration.encrypt_history)
3532
@clear_history = options.fetch(:clear_history, controller.session[:inertia_clear_history] || false)
33+
34+
deep_merge = options.fetch(:deep_merge, configuration.deep_merge_shared_data)
35+
passed_props = options.fetch(:props, component.is_a?(Hash) ? component : @controller.__send__(:inertia_view_assigns))
36+
@props = merge_props(shared_data, passed_props, deep_merge)
37+
38+
@component = resolve_component(component)
39+
3640
@controller.instance_variable_set('@_inertia_rendering', true)
3741
controller.inertia_meta.add(options[:meta]) if options[:meta]
3842
end
@@ -81,8 +85,8 @@ def shared_data
8185
#
8286
# Functionally, this permits using either string or symbol keys in the controller. Since the results
8387
# is cast to json, we should treat string/symbol keys as identical.
84-
def merge_props(shared_props, props)
85-
if @deep_merge
88+
def merge_props(shared_props, props, deep_merge)
89+
if deep_merge
8690
shared_props.deep_symbolize_keys.deep_merge!(props.deep_symbolize_keys)
8791
else
8892
shared_props.symbolize_keys.merge(props.symbolize_keys)
@@ -91,13 +95,12 @@ def merge_props(shared_props, props)
9195

9296
def computed_props
9397
# rubocop:disable Style/MultilineBlockChain
94-
merge_props(shared_data, props)
95-
.then do |merged_props| # Always keep errors in the props
98+
@props
99+
.tap do |merged_props| # Always keep errors in the props
96100
if merged_props.key?(:errors) && !merged_props[:errors].is_a?(BaseProp)
97101
errors = merged_props[:errors]
98102
merged_props[:errors] = InertiaRails.always { errors }
99103
end
100-
merged_props
101104
end
102105
.then { |props| deep_transform_props(props) } # Internal hydration/filtering
103106
.then { |props| configuration.prop_transformer(props: props) } # Apply user-defined prop transformer

spec/dummy/app/controllers/inertia_render_test_controller.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,17 @@ def deferred_props
129129
}
130130
end
131131

132+
inertia_share only: [:shared_deferred_props] do
133+
{
134+
grit: InertiaRails.defer { 'intense' },
135+
}
136+
end
137+
def shared_deferred_props
138+
render inertia: 'TestComponent', props: {
139+
name: 'Brian',
140+
}
141+
end
142+
132143
def scroll_test
133144
pagy = (defined?(Pagy::Offset) ? Pagy::Offset : Pagy).new(
134145
next: 2,
@@ -141,6 +152,21 @@ def scroll_test
141152
}
142153
end
143154

155+
inertia_share only: [:shared_scroll_test] do
156+
pagy = (defined?(Pagy::Offset) ? Pagy::Offset : Pagy).new(
157+
next: 2,
158+
page: 1,
159+
count: 100
160+
)
161+
{
162+
users: InertiaRails.scroll(pagy) { [{ id: 1, name: 'User 1' }, { id: 2, name: 'User 2' }] },
163+
}
164+
end
165+
166+
def shared_scroll_test
167+
render inertia: 'TestComponent'
168+
end
169+
144170
def prepend_merge_test
145171
render inertia: 'TestComponent', props: {
146172
prepend_prop: InertiaRails.merge(prepend: true) { %w[item1 item2] },

spec/dummy/config/routes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
get 'except_props' => 'inertia_render_test#except_props'
3939
get 'merge_props' => 'inertia_render_test#merge_props'
4040
get 'deferred_props' => 'inertia_render_test#deferred_props'
41+
get 'shared_deferred_props' => 'inertia_render_test#shared_deferred_props'
4142
get 'scroll_test' => 'inertia_render_test#scroll_test'
43+
get 'shared_scroll_test' => 'inertia_render_test#shared_scroll_test'
4244
get 'prepend_merge_test' => 'inertia_render_test#prepend_merge_test'
4345
get 'nested_paths_test' => 'inertia_render_test#nested_paths_test'
4446
get 'reset_test' => 'inertia_render_test#reset_test'

spec/inertia/rendering_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,27 @@
661661
end
662662
end
663663

664+
context 'shared scroll props rendering' do
665+
let(:headers) { { 'X-Inertia' => true } }
666+
667+
before do
668+
# Create a mock controller action that returns scroll props
669+
get '/shared_scroll_test', headers: headers
670+
end
671+
672+
it 'includes scroll props metadata in response without reset' do
673+
expect(response).to be_successful
674+
expect(response.parsed_body['scrollProps']).to include('users')
675+
expect(response.parsed_body['scrollProps']['users']).to include(
676+
'pageName' => 'page',
677+
'currentPage' => 1,
678+
'nextPage' => 2,
679+
'previousPage' => nil,
680+
'reset' => false
681+
)
682+
end
683+
end
684+
664685
context 'prepend merge props rendering' do
665686
let(:headers) { { 'X-Inertia' => true } }
666687

@@ -759,6 +780,23 @@
759780
expect(response.parsed_body['deferredProps']).to eq(nil)
760781
end
761782
end
783+
784+
context 'with shared data' do
785+
let(:headers) { { 'X-Inertia' => true } }
786+
787+
before { get shared_deferred_props_path, headers: headers }
788+
789+
it 'does not include defer props inside props in first load' do
790+
expect(response.parsed_body['props']).to eq({ 'name' => 'Brian' })
791+
end
792+
793+
it 'returns deferredProps' do
794+
expect(response.parsed_body['deferredProps']).to eq(
795+
'default' => ['grit']
796+
)
797+
end
798+
799+
end
762800
end
763801
end
764802

0 commit comments

Comments
 (0)