Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 - yield return or callback won't call in view <%= yield(:sidebar) || render('shared/sidebar') %>

I'm migrating a Website from Rails 2 (latest) to Rails 3 (beta2).
Testing with Ruby 1.9.1p378 and Ruby 1.9.2dev (2010-04-05 trunk 27225)

Stuck in a situation, i don't know which part will work well. Suspect yield is the problem, but don't know exactly.

In my Layout Files I use the following technique quite often:

app/views/layouts/application.html.erb:

<%= yield(:sidebar) || render('shared/sidebar') %>

For Example the partial look like:

app/views/shared/_sidebar.html.erb:

<p>Default sidebar Content. Bla Bla</p>

Now it is time for the key part!
In any view, I want to create a content_for block (optional). This can contain a pice of HTML etc. example below. If this block is set, the pice HTML inside should render in application.html.erb.
If not, Rails should render the Partial at shared/_sidebar.html.erb on the right hand side.

app/views/books/index.html.erb:

<% content_for :sidebar do %>
    <strong>You have to read REWORK, a book from 37signals!</strong>
<% end %>

So you've got the idea. Hopefully. This technique worked well in any Rails 2.x Application.
Now, in Rails 3 (beta2) only the yield Part is working.

|| render('shared/sidebar')

The or side will not process by rails or maybe ruby.

Thanks for input and time!

like image 604
rzar Avatar asked Apr 09 '10 22:04

rzar


People also ask

What does yield do in Rails?

During a method invocation The yield keyword in corporation with a block allows to pass a set of additional instructions. When yield is called in side a method then method requires a block with in it. A block is simply a chunk of code, and yield allows us to inject that code at some place into a method.

What do you use the keyword yield for* in Ruby?

yield is a keyword in Ruby which allow the developer to pass some argument to block from the yield, the number of the argument passed to the block has no limitations, the main advantage of using yield in Ruby, if we face any situation we wanted to our method perform different functions according to calling block, which ...

What is yield tag in rails?

Without any arguments, yield will render the template of the current controller/action. So if you're on the cars/show page, it will render views/cars/show. html. erb . When you pass yield an argument, it lets you define content in your templates that you want to be rendered outside of that template.

What does yield mean Ruby?

yield tells ruby to call the block passed to the method, giving it its argument. yield will produce an error if the method wasn't called with a block where as return statement don't produces error.


3 Answers

Ryan Bates from railscasts.com shows in Episode #227 - Upgrading to Rails 3 Part 3 a solution with content_for?() (video playback at 2:45 Min)

I think, that's the way we should use it:

content_for?(:sidebar) ? yield(:sidebar) : render("shared/sidebar")
like image 145
rzar Avatar answered Nov 09 '22 23:11

rzar


I tested this out and it looks like Rails 3 is returning empty string instead of nil. So, unless they change this before the final release you will have to modify your code to see if the value is blank instead of just nil.

(sidebar = yield(:sidebar)).present? ? sidebar : render("shared/sidebar")
like image 22
Mike Dotterer Avatar answered Nov 10 '22 00:11

Mike Dotterer


I usually set my site title with:

<title><%= ['My Site', yield(:title)].compact.join(' - ') %></title>

Due to this change, it would be ugly to add some conditions, so I created a helper like this:

module ApplicationHelper
    def nil_empty(str)
        str.blank? ? nil : str
    end
end

Then I can do something like:

<title><%= ['My Site', nil_empty(yield :title)].compact.join(' - ') %></title>

It's still ugly, but a little bit less :)

like image 42
Pixoo Avatar answered Nov 09 '22 23:11

Pixoo