2010-12-09 90 views
96

理解Rails與渲染局部變量(以及傳遞局部變量)有關的「魔術」。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.上的人?

+3

在下面的評論中,您說的是rails api文檔不可搜索。你應該試試這個網站:http://apidock.com/rails。它也有ruby和rspec。 – ryeguy 2010-12-09 21:46:21

回答

150

簡短的回答是渲染方法看你傳遞的第一個參數。如果你傳入一個散列(其中包括:partial => 'foo', :locals => {blah blah blah}),那麼它會傳遞所有的參數作爲散列並相應地解析它們。

如果你傳入一個字符串作爲你的第一個參數,它假定第一個參數是你的部分名稱,並將剩下的作爲你的本地傳遞。然而,在隨後的通話中,它實際上分配了:locals => your_locals_argument,在這種情況下,這是整個:locals => {locals hash},而不僅僅是{locals hash};即最終以:locals => {:locals => {locals hash}}而不是:locals => {locals hash}

因此,我的建議是始終以相同的方式始終明確地傳遞值,並且不會有問題。爲了瞭解這一點,我直接去了代碼本身(actionpack/lib/base.rbrender()方法在Rails 2中; Rails 3是不同的)。這是一個很好的練習。

此外,不要擔心「打擾」SO上的人。這就是爲什麼這個網站存在。我甚至從中學到了一些東西。

5

,如果你需要指定:當地人,你需要指定:局部或:模板

<%= render :partial => "rabbits/form", :locals => {...} %> 

應該工作

+0

它與ruby評估散列的方式有關,如果你對這種方式感興趣。 – sethvargo 2010-12-09 20:05:00

+0

事實上,它確實有效......正如我在我的問題中指出的那樣......但是我想知道的是*爲什麼?*以及在哪裏記錄?只有通過觀察來源?而且,如果這是在Rails中查找和理解這些無數細微差別的唯一方法,那麼我想知道如何從源代碼中找到並解釋這個問題。我不能只是點擊「渲染」,然後深入到源代碼(無論如何不是),或者我可以嗎? – Meltemi 2010-12-09 20:08:46

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 

希望這個幫助!

2

爲了更好的體會,我只知道這些用例,因爲在過去的幾年裏我一直在跟蹤Rails,並閱讀了一些新增加的方法。我經常自己犯了一個錯誤,但通常很容易糾正。

這是Rails API的其中一部分,如果你問我的話,它還沒有經過深思熟慮。這些年來它只是積累了越來越多的語法糖,而沒有貶低任何舊的行爲。渲染方法有糖尿病。

爲了讓它更糟,渲染器在控制器和視圖中的行爲不同。我還會查看第一個參數的內容,以查看它是文件,模板,操作還是部分。如果它以斜線開頭,那麼它是一個文件,或類似的東西。

我贊成儘可能使用較短的表示法。因爲短符號確實很好地傳達了意圖。閱讀時,它通常會做你認爲它的作用。寫它並不是那麼簡單。