5 little-known Rails methods

Posted by Eric Chapweske
on Wednesday, April 23

While the next release of Rails appears to be coming up, there’s still plenty of small, useful features from previous releases that aren’t widely used.

A few of my favorites:
  1. query_attribute
  2. polymorphic_path
  3. debug
  4. rake -T `query` ( Not Rails specific, but still handy! )
  5. extract_options!

1. ActiveRecord’s query_attribute

Query methods are available for each of a record’s attributes, providing for a cleaner way to check for the presence of an attribute.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# == Schema Information
# Schema version: 17
#
# Table name: users
#
#  id                    :integer(11)     not null, primary key 
#  first_name            :string(255)     
#  last_name             :string(255) 

# Original
class User < ActiveRecord::Base
  def named?
    !first_name.blank? && !last_name.blank?
  end
end

# Refactored to use query_attribute
class User < ActiveRecord::Base
  def named?
     first_name? && last_name?
  end
end

2. Indifferent links with polymorphic paths.

Rails has polymorphic edit/new/formatted path routing available out of the box. Providing an array will namespace the path with those array parameters. Available Methods: (edit|new|formatted|)polymorphic_path(record_or_hash_or_array)

1
2
3
4
5
6
7
8
9
10

# Before:
<% if @record.is_a?(User) %>
<%= user_path(@record) %>
<% elsif @record.is_a?(Friend)
<%= friend_path(@record) %>
 ... etc.

# After:
<%= polymorphic_path(@record) %>
Quite a few options are supported, and other Rails methods take advantage of polymorphic routing:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Paths can be namespaced:
#=> admin/users/5/edit
edit_polymorphic_path([:admin, @record])

# Polymorphic urls are also internally used by helpers:
# redirects to store_path(@store)
redirect_to @store
  
# builds a form with an action to 'new_admin_stores_path'
#=> <form action="admin/stores/new" ... />
form_for([:admin, Store.new])

# <a href="/stores/5">A store in Minneapolis, MN</a>
link_to @store.name, @store

3. debug

Especially useful when starting out a project, this is quick way to understand what objects are being used in the view.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


<%= debug @user %>

# Yields this in the view:
# - !ruby/object:User 
#  attributes: 
#    salt: 7be4287a1b27426fa6e5b6d733c707dd66425e82
#    updated_at: 2008-04-22 19:01:23
#    crypted_password: abb611def895dac923ba8ea59a78451f77473d5e
#    id: "1"
#    first_name: Eric
#    last_name: Chapweske
#    created_at: 2008-04-06 01:45:33
#  attributes_cache: {}

4. rake -T task

This is a handy Rake feature, and not limited to Rails. Can’t remember the exact syntax for a particular rake task? Trim the results generated with `rake -T` with an optional search parameter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

$rake -T

rake annotate_models                 # Add schema information (as comments)...
rake audit:purge                     # Removes Audit records older than 2 m...
rake db:abort_if_pending_migrations  # Raises an error if there are pending...
... etc.
rake tmp:sockets:clear               # Clears all files in tmp/sockets

// Searching by the task's name

$rake -T db:migrate:r

rake db:migrate:redo   # Rollbacks the database one migration and re migrat...
rake db:migrate:reset  # Resets your database using your migrations for the...

5. extract_options!

While not needed very often, Rails comes bundled with a method to extract the options from methods that utilize the splat operator. This method removes the last object from an array if it’s a Hash, otherwise an empty hash is returned.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


class Story < ActiveRecord::Base

  # Example: 
  # Story.published_and_tagged_with('deep', 'thoughts', :order => 'created_at desc') 
  # The generated options for this method look like this: 
  #=> { :include => :tags, :order => 'created_at desc' }
  def self.published_and_tagged_with(*tag_names)
    options = tag_names.extract_options!
    options[:include] ||= :tags
    
    ...
  end
end

References

I wasn’t able to find any write ups on the above methods, so reading the source code may be the best path if you’re curious about their exact implementations.

Comments

Leave a response

  1. grosserApril 25, 2008 @ 12:15 AM

    I dunno where to put this, since there is no contact form…

    i subscribed using google reader, and i get duplicate items A LOT, please have a look if you are sending valid RSS, or bookmark your feed yourself, it really starts to get annoying…

    mg

  2. JonApril 25, 2008 @ 01:59 PM

    Thanks, mg – we’ve investigated a bit. It looks like our feed is valid, but it could be a few other things (regarding ids/guids or edits). And it only happens in some RSS readers. We’ll see what we can do.

    Anyone have expertise with this sort of thing?

  3. DylanApril 25, 2008 @ 03:38 PM

    polymorphic_path is a huge time saver. thanks for the heads up.

  4. JerodApril 25, 2008 @ 03:45 PM

    Howdy!

    Just wondering if you manually pasted the schema info comments above your model in section 1 or if you know of a way to make Rails do that itself. I always find myself checking schema.rb often when returning to models I haven’t worked on in awhile.

    Thanks for these tips, I’m sure I’ll find uses for them!

  5. Brandt LoftonApril 25, 2008 @ 03:55 PM

    Jerod:

    Checkout the annotate_models plugin, a must have of mine.

  6. kenApril 25, 2008 @ 04:56 PM

    Regarding #4, even more useful than -T is -D. rake -T really does print ”...” at column 75, no matter how wide the terminal is (why oh why?). rake -D prints the whole description.

  7. Aníbal RojasApril 25, 2008 @ 09:14 PM

    Thansk! No more $ rake -tasks | grep whaetever :)

  8. ErikApril 26, 2008 @ 04:08 AM

    Thanks for this post—polymorphic_path is real handy.

  9. jDeppenApril 27, 2008 @ 01:20 AM

    polymorphic_path is awesome, I cleaned up a bunch of my views. I also found #1 to be useful. Thanks a lot.

  10. NetManiacApril 28, 2008 @ 03:02 AM

    @Jerod It is output from Annotate Models plugin

  11. Felipe GiottoApril 29, 2008 @ 04:24 PM

    These are not heavily used methods, but it’s good to remember them!

    Good post!

    Felipe Giotto ;-)

  12. UnfaigoDingbomMay 07, 2008 @ 01:02 PM

    well done, man