为简单起见,测试模板:
# app/views/test.json.jbuilder
json.attr name:
我不知道如何通过其他方式访问它,但您可以在以下位置查看编译后的source
:
一百零二
要查看模板呈现时实际运行的代码,请执行以下操作:
>> ApplicationController.renderer.render(template: "test", locals: {name: "first"})
Rendering test.json.jbuilder
" def _app_views_test_json_jbuilder__1585277848127427767_29960(local_assigns, output_buffer)\n @virtual_path = \"test\";name = local_assigns[:name]; name = name;;__already_defined = defined?(json); json||=JbuilderTemplate.new(self); json.attr name:\n\n json.target! unless (__already_defined && __already_defined != \"method\")\n end\n"
=> TypeError # doesn't actually render
formatted个
def _app_views_test_json_jbuilder__1161877154070863274_90100(local_assigns, output_buffer)
@virtual_path = "test"; # ActionView
name = local_assigns[:name]; # ActionView
name = name;; # ActionView
__already_defined = defined?(json); # Jbuilder
json||=JbuilderTemplate.new(self); # Jbuilder
json.attr name: # Your template
json.target! unless (__already_defined && __already_defined != "method")
# ^ Jbuilder json output
end
如果您没有用括号括起来,则json.target!
将成为name
的值,并且您的模板将返回json.attr
返回的值或您的模板返回的json.partial!
.
It's also fixable if you put a semicolon at the end of this line:
https://github.com/rails/jbuilder/blob/v2.11.5/lib/jbuilder/jbuilder_template.rb#L277
# here v
%{__already_defined = defined?(json); json||=JbuilderTemplate.new(self); #{source};
>> ApplicationController.renderer.render(template: "test", locals: {name: "first"})
=> "{\"attr\":{\"name\":\"first\"}}"
简化版
def json *args
@buffer = [*@buffer, *args]
end
def target
@buffer&.join
ensure
@buffer = nil
end
# ^ this is action view/jbuilder
# v this is jbuilder templates
def good_template name = "first"
json(name:)
target
end
# same as doing:
# `json name: target`
def bad_template name = "first"
json name:
target
end
>> good_template
=> "{:name=>\"first\"}"
>> bad_template
=> [{:name=>nil}] # Array instead of a String, if we had a controller
# there would be a TypeError somewhere.
So method hash:
is still an iffy syntax and much less obvious in a template. Just use parenthesis:
https://bugs.ruby-lang.org/issues/18396