Skip to content

Commit 9ea92d4

Browse files
committed
Also pass local_assigns to strict locals templates
If one of the locals conflict with a keyword, typically `class`. The potentially confusing part however is that if you define a default value, `local_assigns` won't respect it.
1 parent 770b353 commit 9ea92d4

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

actionview/lib/action_view/base.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ def _run(method, template, locals, buffer, add_to_stack: true, has_strict_locals
265265

266266
if has_strict_locals
267267
begin
268-
public_send(method, buffer, **locals, &block)
268+
public_send(method, locals, buffer, **locals, &block)
269269
rescue ArgumentError => argument_error
270270
raise(
271271
ArgumentError,

actionview/lib/action_view/template.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,9 @@ def compiled_source
439439
method_arguments =
440440
if set_strict_locals
441441
if set_strict_locals.include?("&")
442-
"output_buffer, #{set_strict_locals}"
442+
"local_assigns, output_buffer, #{set_strict_locals}"
443443
else
444-
"output_buffer, #{set_strict_locals}, &_"
444+
"local_assigns, output_buffer, #{set_strict_locals}, &_"
445445
end
446446
else
447447
"local_assigns, output_buffer, &_"
@@ -500,11 +500,12 @@ def compile(mod)
500500

501501
return unless strict_locals?
502502

503-
parameters = mod.instance_method(method_name).parameters - [[:req, :output_buffer]]
503+
parameters = mod.instance_method(method_name).parameters
504+
parameters -= [[:req, :local_assigns], [:req, :output_buffer]]
505+
504506
# Check compiled method parameters to ensure that only kwargs
505507
# were provided as strict locals, preventing `locals: (foo, *foo)` etc
506508
# and allowing `locals: (foo:)`.
507-
508509
non_kwarg_parameters = parameters.select do |parameter|
509510
![:keyreq, :key, :keyrest, :nokey].include?(parameter[0])
510511
end

actionview/test/template/template_test.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,11 @@ def test_rails_injected_locals_can_be_specified
238238
assert_equal "Hello", render(message: "Hello", implicit_locals: %i[message])
239239
end
240240

241+
def test_rails_local_assigns_and_strict_locals
242+
@template = new_template("<%# locals: (class: ) -%>\n<%= local_assigns[:class] %>")
243+
assert_equal "some-class", render(class: "some-class", implicit_locals: %i[message])
244+
end
245+
241246
def test_rails_injected_locals_can_be_specified_as_kwargs
242247
@template = new_template("<%# locals: (message: 'Hello', **kwargs) -%>\n<%= kwargs[:message_counter] %>-<%= kwargs[:message_iteration] %>")
243248
assert_equal "1-2", render(message: "Hello", message_counter: 1, message_iteration: 2, implicit_locals: %i[message_counter message_iteration])

0 commit comments

Comments
 (0)