43

I'm not sure if I'm doing the best approach here, but I have a block of data that I want to show after a search is done and to not be there at all before. First of all, there is nothing to show, and second the model it references is nil so it throws an exception.

I placed this block in a partial template and added it the appropriate spot in my layout. Is there a way to cleanly render the partial conditionally? Is there a better way to approach this problem?

Donald Hughes
  • 6,627
  • 8
  • 35
  • 46

3 Answers3

58

Ruby allows you to do nice things like this:

<%= render :partial => "foo/bar" if @conditions %>

To make this a bit easier to read and understand, it can be written as:

<%= render(:partial => "foo/bar") if @conditions %>

render is a function, and you pass it a hash that tells it which partial to render. Ruby allows you to put things on one line (which often makes them more readable and concise, especially in views), so the if @conditions section is just a regular if statement. It can also be done like:

<% if @conditions %>
  <%= render :partial => "foo/bar" %>
<% end %>

Edit:

Ruby also allows you to use the unless keyword in place of if. This makes code even more readable, and stops you from having to do negative comparisons.

<%= render :partial => "foo/bar" if !@conditions %>
#becomes
<%= render :partial => "foo/bar" unless @conditions %>
Mike Trpcic
  • 25,305
  • 8
  • 78
  • 114
  • `<%= render :partial => "foo/bar" unless @conditions %>` is the conciseness I was looking for. And, regarding your comment below, I agree that it would be foolish to be completely dogmatic about the separation of concerns. That's actually a reason I like Rails templating flexibility versus a system like Django has. But I do like to limit it when possible. Nightmare flashbacks to my days doing classic asp, I guess. Thanks for the help! – Donald Hughes Mar 04 '10 at 03:51
  • No problem. The hard part from switching from something like ASP is defining where your application/business logic ends, and where the view logic begins. – Mike Trpcic Mar 04 '10 at 04:06
9

One easy way is to use a helper method. Helpers tend to be a bit cleaner than putting logic directly in the view.

So, your view might be something like :

<%= render_stuff_conditionally %>

and your helper would have a method to control this:

def render_stuff_conditionally
  if @contional_check
    render :partial => 'stuff'
  end
end

where obviously things are named more appropriately

Pete
  • 17,885
  • 4
  • 32
  • 30
  • Agreed, putting logic in a helper is best. – bojo Mar 04 '10 at 02:30
  • 1
    I disagree. There's a distinct difference between controller logic and view logic, and this is view logic. It can be accomplished as a concise one-liner like I suggested. This option only makes it harder to find out which conditions are being checked when debugging or maintaining the code. – Mike Trpcic Mar 04 '10 at 03:12
  • 3
    I think it's worth considering the situation and what you're actually gaining from using or not using a helper. If the code you're considering stuffing into a helper will improve the readability of the view, it may be worthwhile for you. If leaving the conditional (or whatever code) inside the view lends to the code being more readable and maintainable then there's that to consider as well. Helpers can end up being a catch-all for all sorts of code, in that case your view code might be beautiful but you've just "squeezed the balloon" (and the mess didn't go away). – Tass May 08 '12 at 18:06
2

Assuming I am following you right, you do this at the view level.

<% if !@my_search_data.nil? %>
<% render :partial => 'foo/bar' %>
<% end %>

Hope that helps. If not, maybe post an example of your code.

bojo
  • 1,407
  • 13
  • 15
  • 1
    That's actually what I did while waiting on a response. It works, but I prefer to avoid conditional logic in a view if reasonably possible. – Donald Hughes Mar 04 '10 at 02:31
  • Pete's solution is the best way to go in that case. – bojo Mar 04 '10 at 02:51
  • @Donald: There is no reason to shy away from logic in views. There is a fine line between "view logic" and "application logic". – Mike Trpcic Mar 04 '10 at 03:13