了解Rails“魔术”关于渲染局部(并将局部传递到其中)。
为什么这样做:
<%= render "rabbits/form" %>
这项工作:
<%= render "rabbits/form", :parent => @warren, :flash => flash %>
但这确实不工作:
<%= render "rabbits/form", :locals => { :parent => @warren, :flash => flash } %>
但这样做:
<%= render :partial =>"rabbits/form", :locals => { :parent => @warren, :flash => flash } %>
另外,我怎样才能查看这些细微差别所以我不需要打扰S.O的人?
答案 0 :(得分:151)
简短的回答是render方法查看传入的第一个参数。如果传入一个哈希(包括:partial => 'foo', :locals => {blah blah blah}
),那么它会将所有参数作为哈希传递并相应地解析它们。
如果传入一个字符串作为第一个参数,它会假定第一个参数是您的部分名称,并将余数作为您的本地传递。但是,在后续调用中,它实际上会分配:locals => your_locals_argument
,在这种情况下是整个:locals => {locals hash}
,而不仅仅是{locals hash}
;即最终得到:locals => {:locals => {locals hash}}
,而不是:locals => {locals hash}
。
所以我的建议只是始终以相同的方式显式传递值,而且你不会遇到问题。为了了解这一点,我直接使用了代码本身(Rails 2中的 actionpack / lib / base.rb ,render()
方法; Rails 3不同)。这是一个很好的练习。
此外,不要担心在SO上“打扰”人们。这就是这个网站存在的原因。我甚至从中学到了一些东西。
答案 1 :(得分:5)
如果您需要指定:locals,则需要指定:partial或:template
<%= render :partial => "rabbits/form", :locals => {...} %>
应该有效
答案 2 :(得分:2)
为了获得荣誉,我只知道这些用例,因为我在过去几年一直关注Rails,并阅读了一条新的方法,即添加了一种新方法。我自己经常犯错误,但通常很容易纠正。
如果你问我,这是Rails API的其中一个部分尚未经过深思熟虑。它多年来积累了越来越多的语法糖,没有弃用任何旧的行为。渲染方法有糖尿病。
更糟糕的是,渲染在控制器和视图中的行为有所不同。我还查看第一个参数的内容,看它是文件,模板,动作还是部分。如果它以斜杠开头,那么它就是一个文件,或类似的东西。
我赞成尽可能使用较短的符号。因为简短的符号确实可以很好地传达意图。阅读时,它通常会按照您的想法执行。写它不是那么直接。
答案 3 :(得分:1)
以下是http://api.rubyonrails.org/classes/ActionView/Rendering.html#method-i-render的渲染方法的来源:
def render(options = {}, locals = {}, &block)
case options
# Here is your last case
when Hash
if block_given?
_render_partial(options.merge(:partial => options.delete(:layout)), &block)
elsif options.key?(:partial)
_render_partial(options)
else
template = _determine_template(options)
lookup_context.freeze_formats(template.formats, true)
_render_template(template, options[:layout], options)
end
when :update
update_page(&block)
else
# here the first three cases
_render_partial(:partial => options, :locals => locals)
end
end
希望这有帮助!