read

When working on your apps, it’s really easy to lose track of the things you still need to do.

You’ll find there are tons of occasions where you spot something that could be refactored, changed, improved, sorted etc. but you may not be able to deal with it right away.

Rails 2 introduced a really cool new feature called annotations so you can leave notes for yourself in your code and then call them back when necessary.

For example, this user model has first_name and last_name attributes but I’d also like to write a method which returns the full name.

class User < ActiveRecord::Base

  def first_name
    "Joe"
  end

  def last_name
    "Bloggs"
  end

end

By adding a comment “TODO add full_name to user” as a note to add this method when I get the chance,

class User < ActiveRecord::Base
  # TODO add full_name to user
  def first_name
    ...

    ...
  end
end

… I can then run …

rake notes

…which will return:

app/models/user.rb:
  * [  2] [TODO] add full_name to user

You’ll notice this shows the file the comment is located in (app/models/user.rb) and the line it is written on (line 2, in square braces).

It also shows the type of note (in this case TODO). You can also add OPTIMIZE and FIXME notes.

TODO = Things you still need to do. OPTIMIZE = Code you need to clean-up, refactor etc. FIXME = Mark a bug or method that needs to be fixed.

rake notes will return all of the annotations you’ve written. If you’d like to show only a particular type of note you can use any of these:

rake notes:todo
rake notes:optimize
rake notes:fixme

You can also specify your own note type like this:

class User < ActiveRecord::Base
  # WOW This is an awesome piece of code!
  def first_name

  end
end

and then call all notes of this type using

rake notes:custom ANNOTATION=WOW

If you’re using TextMate then finding your annotations are even easier – just press shift + ctrl + T. Check out this tip for more TextMate tips.

By default, rails will search all files in your app, test and lib directories. If you’d like to add annotations to your spec files or any other files in your app that are not in subdirectories of app, test or lib then I’d recommend freezing rails to vendor/ and adding any extra directories to the find method in vendor/rails/railties/lib/source_annotation_extractor.rb like so:

# vendor/rails/railties/lib/source_annotation_extractor.rb line 52
def find(dirs=%w(app lib test spec)) # I've added spec to this array
  dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
end

If anybody can think of an easier way to add directories to this method, please leave a comment with your ideas :)