Skip to content

Commit d98e817

Browse files
committed
Do not wrap simple values in procs
1 parent 68410ac commit d98e817

File tree

4 files changed

+56
-33
lines changed

4 files changed

+56
-33
lines changed

lib/inertia_rails/lazy.rb

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
1+
# frozen_string_literal: true
2+
13
module InertiaRails
24
class Lazy
35
def initialize(value = nil, &block)
6+
raise ArgumentError, 'You must provide either a value or a block, not both' if value && block
7+
48
@value = value
59
@block = block
610
end
711

8-
def call
9-
to_proc.call
12+
def call(controller)
13+
value.respond_to?(:call) ? controller.instance_exec(&value) : value
1014
end
1115

12-
def to_proc
13-
# This is called by controller.instance_exec, which changes self to the
14-
# controller instance. That makes the instance variables unavailable to the
15-
# proc via closure. Copying the instance variables to local variables before
16-
# the proc is returned keeps them in scope for the returned proc.
17-
value = @value
18-
block = @block
19-
if value.respond_to?(:call)
20-
value
21-
elsif value
22-
Proc.new { value }
23-
else
24-
block
25-
end
16+
def value
17+
@value.nil? ? @block : @value
2618
end
2719
end
2820
end

lib/inertia_rails/renderer.rb

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,16 @@ def computed_props
7676
end
7777
end
7878

79-
deep_transform_values(
80-
_props,
81-
lambda do |prop|
82-
prop.respond_to?(:call) ? controller.instance_exec(&prop) : prop
79+
deep_transform_values _props do |prop|
80+
case prop
81+
when Lazy
82+
prop.call(controller)
83+
when Proc
84+
controller.instance_exec(&prop)
85+
else
86+
prop
8387
end
84-
)
88+
end
8589
end
8690

8791
def page
@@ -93,10 +97,10 @@ def page
9397
}
9498
end
9599

96-
def deep_transform_values(hash, proc)
97-
return proc.call(hash) unless hash.is_a? Hash
100+
def deep_transform_values(hash, &block)
101+
return block.call(hash) unless hash.is_a? Hash
98102

99-
hash.transform_values {|value| deep_transform_values(value, proc)}
103+
hash.transform_values {|value| deep_transform_values(value, &block)}
100104
end
101105

102106
def partial_keys
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
class ApplicationController < ActionController::Base
2+
def controller_method
3+
'controller_method value'
4+
end
25
end

spec/inertia/lazy_spec.rb

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,44 @@
11
RSpec.describe InertiaRails::Lazy do
22
describe '#call' do
3-
context 'with a value' do
4-
it 'returns the value' do
5-
expect(InertiaRails::Lazy.new('thing').call).to eq('thing')
6-
end
7-
end
3+
subject(:call) { prop.call(controller) }
4+
let(:prop) { described_class.new('value') }
5+
let(:controller) { ApplicationController.new }
6+
7+
it { is_expected.to eq('value') }
88

99
context 'with a callable value' do
10-
it 'returns the result of the callable value' do
11-
expect(InertiaRails::Lazy.new(->{ 'thing' }).call).to eq('thing')
10+
let(:prop) { described_class.new(-> { 'callable' }) }
11+
12+
it { is_expected.to eq('callable') }
13+
14+
context "with false as value" do
15+
let(:prop) { described_class.new(false) }
16+
17+
it { is_expected.to eq(false) }
18+
end
19+
20+
context "with nil as value" do
21+
let(:prop) { described_class.new(nil) }
22+
23+
it { is_expected.to eq(nil) }
24+
end
25+
26+
context "with dependency on the context of a controller" do
27+
let(:prop) { described_class.new(-> { controller_method }) }
28+
29+
it { is_expected.to eq('controller_method value') }
1230
end
1331
end
1432

1533
context 'with a block' do
16-
it 'returns the result of the block' do
17-
expect(InertiaRails::Lazy.new{'thing'}.call).to eq('thing')
34+
let(:prop) { described_class.new { 'block' } }
35+
36+
it { is_expected.to eq('block') }
37+
38+
context "with dependency on the context of a controller" do
39+
let(:prop) { described_class.new { controller_method } }
40+
41+
it { is_expected.to eq('controller_method value') }
1842
end
1943
end
2044
end

0 commit comments

Comments
 (0)