Things you might not know about Ruby on Rails

I have been digging around the Rails source a lot since the last time I shared my discoveries.
Seeing how popular the post was, I have collected a small list of interesting, potentially useful and clever bits of code I have stumbled upon and finally picked up the slack to write about these.

Enumerable.many?

You are probably already familiar with Enumerable.any? and Enumerable.empty? (for checking if the collection has any elements or whether its empty).
Rails extends the Enumerable module with another method for checking if the collection has more than one element.

[1,2,3,4,5,6].many? # => true
[].many? # => false
[1].many # => false

# it also accepts a block
# this example checks if the given list includes more than one number
# evenly divisible with 2
[1,2,3,4].many? { |o| o.multiple_of?(2) }

This method is basically an alias for collection.size > 1.

RecordTagHelper

I bet that there have been a lot of times when you have written view code like this (at least I have):

<div id="product_<%= @product.id %>" class="product my_class">
 ...
</div>

There is a helper which does the same thing with less hassle – RecordTagHelper.
It consist of two methods – content_tag_for and div_for. Both methods accept a model object, optional prefix and options. Additionally the first method accepts a tag name symbol as the first parameter.

With this helper I can rewrite the code as follows:

< % div_for @product, :class => "my_class" do %>
 ...
< % end %>

/* if i want a &lt;span&gt; element instead */
< % content_tag_for :span, @product, :class => "my_class" do %>
 ...
< % end %>

/* you can also specify a prefix */
< % content_tag_for :span, @product, :foo, :class => "my_class" do %>
 ...
< % end %>

/* above example produces this output */
<span id="foo_product_1234" class="product my_class">
</span>

Object.try

This method is very similar to Object.send, accepting a method name, arguments and an optional block.
Difference is that instead of throwing NoMethodError if the method does not exist on the object, it just returns nil.

@name = @user ? @user.name : nil
@user.do_something(1)

# this can be written like this
@name = @user.try(:name)
@user.try(:do_something, 1)

Float.round

As you might already know, ruby does not support float rounding with given precision. It just rounds the float to the closest integer.
[Rails fixes this issue with an extension of its own – Float.round(precision).

x = 1.337
x.round # => 1
x.round(1) # => 1.3
x.round(2) # => 1.33

redirect_to

No, redirect_to is not new for me :)
But let me ask you – how many times have you written code like this?

class FooController < ApplicationController

  def update
    ...
    if @foo.save
      flash[:notice] = "Foo properly saved"
      redirect_to foo_path(@foo) and return
    end
  end

end

In Rails 3, this can be written in a bit cleaner manner.

class FooController < ApplicationController
  def update
    ...
    if @foo.save
      redirect_to foo_path(@foo), :notice => "Foo properly saved"
    # or
      redirect_to foo_path(@foo), :flash => {:notice => "Foo properly saved"}
    end
  end
end

Two options, :alert and :notice are basically aliases for flash[:notice] and flash[:alert]. Remember that this method is only available in Rails 3.

Benchmarkable

This little helper provides you the means to measure the execution time for a piece of code. The results are then logged with the configured log level (:info as default).
The usage itself is really simple – just wrap whatever code you want with the benchmark method call and run your code.

< % benchmark "Process data files", :level => :debug do %>
 < %= expensive_operation %>
< % end %>

This results in something like “Process data files (345.2ms)” in your logs.
API docs for this method can be viewed here.

More stuff you should check out

There are a couple of helper modules which include lots of small but useful helpers. Covering them all would be a bit too long for this post, so I’ll just provide you with the links to API documentation and let you do some exploration on your own.

ActionView::Helpers::NumberHelper – all kinds of trickery for working with numbers.
ActionView::Helpers::SanitizeHelper – tools for content sanitizing.
ActionView::Helpers::TextHelper – methods for formatting, filtering and transforming text.
ActionView::Helpers::DateHelper – helper methods for working with dates.

I encourage you to read a lot of source code, and not only Rails source, but basically anything interesting you can get your hands on (a good place for this is GitHub).

In my opinion reading other peoples code is a very, very good way to learn and discover new tricks and techniques. So stop trolling random forums, refreshing Facebook or whatnot, and start reading interesting code on your spare moments :)

Tanel Suurhans
Tanel is an experienced Software Engineer with strong background in variety of technologies. He is extremely passionate about creating high quality software and constantly explores new technologies.

1 Comment

  • Luca Simone

    Awesome tips! :-)

Liked this post?

There’s more where that came from. Follow us on Facebook, Twitter or subscribe to our RSS feed to get all the latest posts immediately.