Ruby on Rails: provide vs content_for Ruby on Rails: provide vs content_for ruby ruby

Ruby on Rails: provide vs content_for


First of all, what is streaming? Why would you use it?

Streaming is alternate method of rendering pages top-down (outside-in). The default rendering behavior is inside-out. Streaming must be enabled in your controller:

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

According to the documentation:

Streaming may be considered to be overkill for lightweight actions like new or edit. The real benefit of streaming is on expensive actions that, for example, do a lot of queries on the database.

So, if you're not using streaming, is there still a difference?

Yes.

The difference is a template can define multiple content blocks by calling content_for multiple times. Doing so will concatenate the blocks and pass that to the layout:

# 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>

Since provide doesn't continue searching the provided template, only the block passed to the first provide call will be sent to the template:

# 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>


Was curious to see what the difference was, and as Thong Kuah pointed to the api, inside the answer:

This means that, if you have yield :title in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this reason Rails 3.1 introduces a new helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.