Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails: provide vs content_for

I came across the view helper function "provide" today. By looking into its manual I am still confused on how it is different from "content_for".

provide(name, content = nil, &block)

The same as content_for but when used with streaming flushes straight back to the layout. In other words, if you want to concatenate several times to the same buffer when rendering a given template, you should use content_for, if not, use provide to tell the layout to stop looking for more contents.

Question 1: this is quite abstract to me - could anyone flesh it out by giving a demonstrative example?

Question 2: working with asset pipeline, which performs better and why?

Thanks!

like image 275
Bruce Avatar asked Jan 07 '15 07:01

Bruce


People also ask

What is the difference between Content_for and yield in rails?

They are opposite ends of the rendering process, with yield specifying where content goes, and content_for specifying what the actual content is.

How can you tell Rails to render without a layout?

By default, if you use the :text option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the layout: true option.

How should you use nested layouts in rails?

Rails provides us great functionality for managing layouts in a web application. The layouts removes code duplication in view layer. You are able to slice all your application pages to blocks such as header, footer, sidebar, body and etc.

What is render partial in rails?

Rails Guides describes partials this way: Partial templates - usually just called "partials" - are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.


1 Answers

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

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> 
like image 179
rodamn Avatar answered Sep 23 '22 17:09

rodamn