Pages

Wednesday, August 5, 2015

try(), try() again in Rails

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.  Let’s look at some very simple code from a Rails view.

Before

Here’s a simple example of code you might replace with try(). Say you’ve got a Productmodel 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:
  <!-- products/show.html.erb (before) -->
  <h1><%= @product.name %></h1>

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

  <% if current_user && current_user.is_admin? %>
    <%= link_to 'Edit', edit_product_path(@product) %>
  <% end %>
 try() can help us in a couple of places here:

  <!-- products/show.html.erb (after) -->
  <h1><%= @product.name %></h1>

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

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

With arguments and blocks

You can pass arguments and blocks to try():
  > @manufacturer.products.first.try(:enough_in_stock?, 32)
  # => "Yes"
  
  > @manufacturer.products.try(:collect) { |p| p.name }
  # => ["3DS", "Wii"]
  

Chaining

You can chain multiple try() methods together. In another contrived example, say you’ve got a method in yourManufacturer model that sends the manufacturer a message whenever called.
  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."


No comments:

Post a Comment