Skip to content

Commit 24944ee

Browse files
BrandonSharBrandon Shar
andauthored
Mimic Rails behavior for instance props and rendering (#81)
* Mimic some rails behavior by using instance variables as props, defaulting renders, and no renders at all * fix specs that were affected by calling a method on a mocked controller * code cleanup * Dont magically provide props if props are manually specified, require instance props to be opt in * Remove inertia_render helper and enable render inertia: true syntax * remove leftover method from refactoring Co-authored-by: Brandon Shar <[email protected]>
1 parent 32a2506 commit 24944ee

File tree

7 files changed

+111
-8
lines changed

7 files changed

+111
-8
lines changed

lib/inertia_rails/controller.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ def inertia_share(**args, &block)
2020
InertiaRails.share_block(block) if block
2121
end
2222
end
23+
24+
def use_inertia_instance_props
25+
before_action do
26+
@_inertia_instance_props = true
27+
@_inertia_skip_props = view_assigns.keys + ['_inertia_skip_props']
28+
end
29+
end
30+
end
31+
32+
def default_render
33+
if InertiaRails.default_render?
34+
render(inertia: true)
35+
else
36+
super
37+
end
2338
end
2439

2540
def redirect_to(options = {}, response_options = {})
@@ -36,6 +51,11 @@ def redirect_back(fallback_location:, allow_other_host: true, **options)
3651
)
3752
end
3853

54+
def inertia_view_assigns
55+
return {} unless @_inertia_instance_props
56+
view_assigns.except(*@_inertia_skip_props)
57+
end
58+
3959
private
4060

4161
def inertia_layout

lib/inertia_rails/inertia_rails.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def self.ssr_url
3232
Configuration.ssr_url
3333
end
3434

35+
def self.default_render?
36+
Configuration.default_render
37+
end
38+
3539
def self.html_headers
3640
self.threadsafe_html_headers || []
3741
end
@@ -66,6 +70,7 @@ module Configuration
6670
mattr_accessor(:version) { nil }
6771
mattr_accessor(:ssr_enabled) { false }
6872
mattr_accessor(:ssr_url) { 'http://localhost:13714' }
73+
mattr_accessor(:default_render) { false }
6974

7075
def self.evaluated_version
7176
self.version.respond_to?(:call) ? self.version.call : self.version

lib/inertia_rails/renderer.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ class Renderer
77
attr_reader :component, :view_data
88

99
def initialize(component, controller, request, response, render_method, props:, view_data:)
10-
@component = component
10+
@component = component.is_a?(TrueClass) ? "#{controller.controller_path}/#{controller.action_name}" : component
1111
@controller = controller
1212
@request = request
1313
@response = response
1414
@render_method = render_method
15-
@props = props || {}
15+
@props = props || controller.inertia_view_assigns
1616
@view_data = view_data || {}
1717
end
1818

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class InertiaRailsMimicController < ApplicationController
2+
before_action :enable_inertia_default, only: :default_render_test
3+
use_inertia_instance_props
4+
5+
def instance_props_test
6+
@name = 'Brandon'
7+
@sport = 'hockey'
8+
9+
render inertia: 'TestComponent'
10+
end
11+
12+
def default_render_test
13+
@name = 'Brian'
14+
end
15+
16+
def provided_props_test
17+
@name = 'Brian'
18+
19+
render inertia: 'TestComponent', props: {
20+
sport: 'basketball',
21+
}
22+
end
23+
24+
def default_component_test
25+
render inertia: true
26+
end
27+
28+
def enable_inertia_default
29+
InertiaRails.configure do |config|
30+
config.default_render = true
31+
end
32+
end
33+
end

spec/dummy/config/routes.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,10 @@
2828
get 'lazy_props' => 'inertia_render_test#lazy_props'
2929
get 'non_inertiafied' => 'inertia_test#non_inertiafied'
3030

31+
get 'instance_props_test' => 'inertia_rails_mimic#instance_props_test'
32+
get 'default_render_test' => 'inertia_rails_mimic#default_render_test'
33+
get 'default_component_test' => 'inertia_rails_mimic#default_component_test'
34+
get 'provided_props_test' => 'inertia_rails_mimic#provided_props_test'
35+
3136
inertia 'inertia_route' => 'TestComponent'
3237
end

spec/inertia/rails_mimic_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require_relative '../../lib/inertia_rails/rspec'
2+
3+
RSpec.describe 'rendering when mimicking rails behavior', type: :request, inertia: true do
4+
5+
context 'the props are provided by instance variables' do
6+
it 'has the props' do
7+
get instance_props_test_path
8+
9+
expect_inertia.to have_exact_props({'name' => 'Brandon', 'sport' => 'hockey'})
10+
end
11+
end
12+
13+
context 'props are explicitly provided' do
14+
it 'only includes the provided props' do
15+
get provided_props_test_path
16+
17+
expect_inertia.to have_exact_props({'sport': 'basketball'})
18+
end
19+
end
20+
21+
context 'no component name is provided' do
22+
it 'has the correct derived component name' do
23+
get default_component_test_path
24+
25+
expect_inertia.to render_component('inertia_rails_mimic/default_component_test')
26+
end
27+
end
28+
29+
context 'no render is done at all and default_render is enabled' do
30+
it 'renders via inertia' do
31+
get default_render_test_path
32+
33+
expect_inertia.to render_component('inertia_rails_mimic/default_render_test')
34+
expect_inertia.to include_props({'name' => 'Brian'})
35+
end
36+
end
37+
end
38+

spec/inertia/rendering_spec.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
RSpec.describe 'rendering inertia views', type: :request do
22
subject { response.body }
33

4+
let(:controller) { double('Controller', inertia_view_assigns: {})}
5+
46
context 'first load' do
5-
let(:page) { InertiaRails::Renderer.new('TestComponent', '', request, response, '', props: nil, view_data: nil).send(:page) }
7+
let(:page) { InertiaRails::Renderer.new('TestComponent', controller, request, response, '', props: nil, view_data: nil).send(:page) }
68

79
context 'with props' do
8-
let(:page) { InertiaRails::Renderer.new('TestComponent', '', request, response, '', props: {name: 'Brandon', sport: 'hockey'}, view_data: nil).send(:page) }
10+
let(:page) { InertiaRails::Renderer.new('TestComponent', controller, request, response, '', props: {name: 'Brandon', sport: 'hockey'}, view_data: nil).send(:page) }
911
before { get props_path }
1012

1113
it { is_expected.to include inertia_div(page) }
@@ -37,7 +39,7 @@
3739
end
3840

3941
context 'subsequent requests' do
40-
let(:page) { InertiaRails::Renderer.new('TestComponent', '', request, response, '', props: {name: 'Brandon', sport: 'hockey'}, view_data: nil).send(:page) }
42+
let(:page) { InertiaRails::Renderer.new('TestComponent', controller, request, response, '', props: {name: 'Brandon', sport: 'hockey'}, view_data: nil).send(:page) }
4143
let(:headers) { {'X-Inertia' => true} }
4244

4345
before { get props_path, headers: headers }
@@ -62,7 +64,7 @@
6264

6365
context 'partial rendering' do
6466
let (:page) {
65-
InertiaRails::Renderer.new('TestComponent', '', request, response, '', props: { sport: 'hockey'}, view_data: nil).send(:page)
67+
InertiaRails::Renderer.new('TestComponent', controller, request, response, '', props: { sport: 'hockey'}, view_data: nil).send(:page)
6668
}
6769
let(:headers) {{
6870
'X-Inertia' => true,
@@ -92,7 +94,7 @@
9294
context 'lazy prop rendering' do
9395
context 'on first load' do
9496
let (:page) {
95-
InertiaRails::Renderer.new('TestComponent', '', request, response, '', props: { name: 'Brian'}, view_data: nil).send(:page)
97+
InertiaRails::Renderer.new('TestComponent', controller, request, response, '', props: { name: 'Brian'}, view_data: nil).send(:page)
9698
}
9799
before { get lazy_props_path }
98100

@@ -101,7 +103,7 @@
101103

102104
context 'with a partial reload' do
103105
let (:page) {
104-
InertiaRails::Renderer.new('TestComponent', '', request, response, '', props: { sport: 'basketball', level: 'worse than he believes', grit: 'intense'}, view_data: nil).send(:page)
106+
InertiaRails::Renderer.new('TestComponent', controller, request, response, '', props: { sport: 'basketball', level: 'worse than he believes', grit: 'intense'}, view_data: nil).send(:page)
105107
}
106108
let(:headers) {{
107109
'X-Inertia' => true,

0 commit comments

Comments
 (0)