Skip to content

Files

78 lines (54 loc) · 3.18 KB

2011-04-28-rails-try-method.markdown

File metadata and controls

78 lines (54 loc) · 3.18 KB
layout title excerpt
post
try(), try() again in Rails
The very convenient try() method has been available to Rails developers since version 2.3, but it's easy to forget if you're not in the habit of using it. Here's a brief primer.

In Rails, try() lets you call methods on an object without having to worry about the possibility of that object being nil and thus raising an exception. I know I sometimes forget about it, and I've looked at enough code from other developers to know that I'm not the only one. So today I'd like to give you a brief introduction to the method (and hopefully ingrain it a little deeper into my own brain). Let's look at some very simple code from a Rails view.

**Disclaimer:** While handy, this technique is not a replacement for good techniques like validations and default database values. Don't get lazy.

Before

Here's a simple example of code you might replace with try(). Say you've got a (rather contrived) Product model in your project. A Product may or may not have a known manufacturer, and some links you only want to display if a user is logged in and has administrator rights:

{% highlight erb %}

<%= @product.name %>

<% unless @product.manufacturer.nil? %> <%= @product.manufacturer.name %> <% end %>

<% if current_user && current_user.is_admin? %> <%= link_to 'Edit', edit_product_path(@product) %> <% end %> {% endhighlight %}

Like I said, it's contrived, but it should give you the idea. try() can help us in a couple of places here:

{% highlight erb %}

<%= @product.name %>

<%= @product.manufacturer.try(:name) %>

<% if current_user.try(:is_admin?) %> <%= link_to 'Edit', edit_product_path(@product) %> <% end %> {% endhighlight %}

With arguments and blocks

You can pass arguments and blocks to try():

{% highlight ruby %}

@manufacturer.products.first.try(:enough_in_stock?, 32)

=> "Yes"

@manufacturer.products.try(:collect) { |p| p.name }

=> ["3DS", "Wii"]

{% endhighlight %}

Chaining

You can chain multiple try() methods together. In another contrived example, say you've got a method in your Manufacturer model that sends the manufacturer a message whenever called.

{% highlight ruby %} class Manufacturer < ActiveRecord::Base has_many :products

def contact
  "Manufacturer has been contacted."
end

end

Product.first.try(:manufacturer).try(:contact) #=> nil Product.last.try(:manufacturer).try(:contact) #=> "Manufacturer has been contacted." {% endhighlight %}

Further reading

You can start with the Rails docs on try(). Rails' inclusion of try() was inspired by Chris Wanstrath's post about adding try() to Ruby. Raymond Law at Intridea has a clever way to chain multiple calls to try(). And Scott Harvey has shared a more practical example of try().