web-dev-qa-db-ja.com

Ruby on Rails:提供vs content_for

今日、ビューヘルパー関数「提供」に出くわしました。そのマニュアルを調べても、「content_for」との違いについてはまだ混乱しています。

provide(name、content = nil、&block)

Content_forと同じですが、ストリーミングで使用すると、レイアウトに直接フラッシュします。つまり、特定のテンプレートをレンダリングするときに同じバッファーに複数回連結する場合は、content_forを使用する必要があります。そうでない場合は、provideを使用して、レイアウトにコンテンツの検索を停止するように指示します。

質問1:これは私には非常に抽象的です-実証的な例を挙げて誰かがそれを具体化できますか?

質問2:アセットパイプラインを使用すると、パフォーマンスが向上しますが、その理由は何ですか?

ありがとう!

27
Bruce

まず、ストリーミングとは何ですか?なぜそれを使うのですか?

ストリーミングは、ページをトップダウン(アウトサイドイン)でレンダリングする別の方法です。デフォルトのレンダリング動作は裏返しです。コントローラでストリーミングを有効にする必要があります。

class MyController
  def action
    render stream: true # Streaming enabled
  end
end

ドキュメント によると:

ストリーミングは、新規または編集などの軽量アクションにはやり過ぎと見なされる場合があります。ストリーミングの本当の利点は、たとえば、データベースに対して多くのクエリを実行する高価なアクションにあります。

それで、ストリーミングを使用していない場合でも、違いはありますか?

はい。

違いは、テンプレートがcontent_forを複数回呼び出すことにより、複数のコンテンツブロックを定義できることです。そうすることで、ブロックが連結され、レイアウトに渡されます。

# layout.html.erb
<div class="heading"><%= yield :surprise %></div>
<div class="body">
   <p><%= yield %></p>
   <p>But it's not very interesting...</p>
</div>

# template.html.erb
<%= content_for :surprise, "Hello" %>
I've got your content!
<%= content_for :surprise, ", World!" %>

# Generated HTML
<div class="heading">Hello, World!</div>
<div class="body">
   <p>I've got your content!</p>
   <p>But it's not very interesting...</p>
</div>

provideは提供されたテンプレートの検索を続行しないため、最初のprovide呼び出しに渡されるブロックのみが検索されます。テンプレートに送信:

# layout.html.erb
<div class="heading"><%= yield :title %></div>

# template.html.erb
<%= provide :title, "Foo" %>
<%= provide :title, "bar" %>

# Generated HTML
<div class="heading">Foo</div>
25
rodamn

違いが何であるかを知りたくて、 Thong Kuah がAPIを指していたので、答えの中に:

つまり、レイアウトにyield:titleがあり、ストリーミングを使用する場合は、タイトルとすべてのアセットをストリーミングする前に、テンプレート全体をレンダリングする(そして最終的にはすべてのクエリをトリガーする)必要があり、ストリーミングの目的が失われます。このため、Rails 3.1は、content_forと同じことを行うが、他のエントリの検索を停止してレンダリングを続行するようにレイアウトに指示する、provideという新しいヘルパーを導入します。

6
rtfminc