Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking for nil in view in Ruby on Rails

I've been working with Rails for a while now and one thing I find myself constantly doing is checking to see if some attribute or object is nil in my view code before I display it. I'm starting to wonder if this is always the best idea.

My rationale so far has been that since my application(s) rely on user input unexpected things can occur. If I've learned one thing from programming in general it's that users inputting things the programmer didn't think of is one of the biggest sources of run-time errors. By checking for nil values I'm hoping to sidestep that and have my views gracefully handle the problem.

The thing is though I typically for various reasons have similar nil or invalid value checks in either my model or controller code. I wouldn't call it code duplication in the strictest sense, but it just doesn't seem very DRY. If I've already checked for nil objects in my controller is it okay if my view just assumes the object truly isn't nil? For attributes that can be nil that are displayed it makes sense to me to check every time, but for the objects themselves I'm not sure what is the best practice.

Here's a simplified, but typical example of what I'm talking about:

controller code

def show
    @item = Item.find_by_id(params[:id])

    @folders = Folder.find(:all, :order => 'display_order')

    if @item == nil or @item.folder == nil
        redirect_to(root_url) and return
    end
end

view code

<% if @item != nil %>
    display the item's attributes here

    <% if @item.folder != nil %>
        <%= link_to @item.folder.name, folder_path(@item.folder) %>
    <% end %>
<% else %>
    Oops! Looks like something went horribly wrong!
<% end %>

Is this a good idea or is it just silly?

like image 519
seaneshbaugh Avatar asked May 01 '10 07:05

seaneshbaugh


People also ask

How do you check if it is nil in Rails?

In Ruby, you can check if an object is nil, just by calling the nil? on the object... even if the object is nil. That's quite logical if you think about it :) Side note : in Ruby, by convention, every method that ends with a question mark is designed to return a boolean (true or false).

What is nil in Ruby on Rails?

nil is a special Ruby data type that means "nothing". It's equivalent to null or None in other programming languages.

How do you check if something is null in Ruby?

You can check if an object is nil (null) by calling present? or blank? . @object. present? this will return false if the project is an empty string or nil .

Is nil or empty Ruby?

Well, nil is a special Ruby object used to represent an “empty” or “default” value. It's also a “falsy” value, meaning that it behaves like false when used in a conditional statement.


2 Answers

No you should use

<% if @item.nil? %>

for example

@item1=nil
if @item1.nil? ### true
@item2 = ""
if @item2.nil? ### false
@item3 = []
if @item3.nil? ### false
@item4 = {}
if @item4.nil? ### false

To check An object is blank if it‘s false, empty, or a whitespace string.

use

<% if @item.blank? %>

ref:- this

for example

@item1=nil
if @item1.blank? #### true
@item2 = ""
if @item2.blank? #### true
@item3 = []
if @item3.blank? #### true
@item4 = {}
if @item4.blank? #### true
like image 70
Salil Avatar answered Sep 23 '22 12:09

Salil


Your example code remade:

controller code. ( I assume this is ItemsController )

def show
  # This will fail with 404 if item is not found
  # You can config rails to pretty much render anything on Error 404
  @item = Item.find(params[:id])

  # doesn't seem to be used in the view
  # @folders = Folder.find(:all, :order => 'display_order')


  # this is not needed anymore, or should be in the Error 404 handler
  #if @item == nil or @item.folder == nil
  #  redirect_to(root_url) and return
  #end
end

view code, since the controller made sure we have @item

#display the item's attributes here

<%= item_folder_link(@item) %>

helper code:

# display link if the item has a folder
def item_folder_link(item)
  # I assume folder.name should be a non-blank string
  # You should properly validate this in folder model
  link_to( item.folder.name, folder_path(item.folder) ) if item.folder
end

Anyway, I try to keep view very very simple. Usually if I see loops and conditionals in views, I try to refactor them into helpers.

like image 20
Aaron Qian Avatar answered Sep 23 '22 12:09

Aaron Qian