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.
[].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>
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:
...
< % end %>
/* if i want a <span> 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.
@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.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?
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.
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.
< %= 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 :)
1 Comment
Awesome tips! :-)