Rails:ローカルをパーシャルに渡すための構文について混乱


99

パーシャルのレンダリング(およびローカルへの渡し)に関して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 } %>

また、これらのニュアンスを調べるにはどうすればよいので、SOで人を煩わせる必要はありませんか?


3
以下のコメントで、rails api docsはそれほど検索可能ではないと言っていました。代わりにこのサイトを試す必要があります:apidock.com/rails。また、そこにはrubyとrspecがあります。
ryeguy

回答:


152

簡単に言えば、renderメソッドは渡した最初の引数を調べます。ハッシュ(を含む: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のメソッド。Rails3は異なります)。それは良い運動です。

さらに、SOで人々を「嫌悪感」にする心配はありません。それがこのサイトが存在する理由です。私はこれからも何かを学びました。


5

:localsを指定する必要がある場合は、:partialまたは:templateを指定する必要があります

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

うまくいくはず


あなたがその方法に興味があるなら、それはルビーがハッシュを評価する方法と関係があります。
sethvargo 2010

確かにそれは機能します..私の質問で指定したように...しかし、なぜ私が疑問に思っているのはなぜですか?そしてこれはどこに文書化されていますか?ソースを見るだけで?そして、それがRailsの無数のニュアンスを見つけて理解するための唯一の方法である場合、ソースからこれを見つけて解釈する方法場所について疑問に思っています。「レンダー」をクリックしてソースにドリルダウンすることはできません(とにかくTextMateではできません)。
Meltemi

1
ああ!だからあなたは実際に興味があります:)。はい、これらのことを理解する唯一の方法は、a。)あなたがしたように直感を持って、b。)ソースコードを表示することです。ソースをドリルダウンする方法はわかりませんが...申し訳ありません
sethvargo

わかった、噛むよ…どうやってこの種のもの調べているの?あなたはあなたをただ掘り下げるのclone https://github.com/rails/rails.gitですか?またはより良い方法はありますか?しかし、申し訳ありませんが、私はRoRのは比較的新しいだとまだRailsのドキュメントを検索する...が、そのようなことは良い/簡単/一貫性のある方法発見していないISいずれかを。http://api.rubyonrails.org/簡単に検索できません。そしてgitからのソースもどちらでもありません... ため息
Meltemi

私は決してエキスパートではありませんが、Aptana studioを使用しています。Eclipseと同じプラットフォームで構築されています(ご存じの場合)。それはあなたが言ったように「クリック」してトレースすることを可能にします。コード内検索を行うこともでき、ターミナルなどが組み込まれています。注意-かなり大きなファイル
sethvargo

2

正直に言うと、ここ数年はRailsに追いついており、新しい方法が追加されたというアナウンスを読んでいるため、これらのユースケースについてのみ知っています。私はよく自分で間違えますが、通常は簡単に修正できます。

あなたが私に尋ねれば、それは完全に熟考されていないRails APIのそれらの部分の1つです。古い動作を非推奨にすることなく、それは長年にわたってますます構文糖を蓄積しました。renderメソッドには糖尿病があります。

さらに悪いことに、レンダリングはコントローラーとビューで異なる動作をします。また、最初の引数の内容を調べて、それがファイル、テンプレート、アクション、または部分的なものかどうかを確認します。スラッシュで始まる場合、それはファイルかそのようなものです。

私は可能な限り短い表記法を使用することに賛成です。短い表記は意図を非常によく伝えるからです。それを読むとき、それは通常あなたがそれをするのを思うことをします。パーシャルを書くのは簡単ではありません。


1

以下は、http//api.rubyonrails.org/classes/ActionView/Rendering.html#method-i-renderの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

この助けを願っています!


これは役に立ちます、ありがとう!しかし、それは私が自分自身を助けるのに役立ちません...もしあなたが私が何を意味しているのか知っているなら...
Meltemi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.