Ruby on Rails: annotations productivity rake tasks todo
by bseanvt
leave a comment
TODO and Custom Annotations in Rails Applications
While writing software it’s common to leave comments for your future self. For instance, if you have written some code but realize that it should be refactored to be more efficient, you may place something along the lines of “TODO: change active record find method and replace w/ a custom sql select finder “. With rails, if you follow this convention, you can get a list of your annotations with a rake task.
rake notes:todo
which will print out the file where the the todo was found along with the line number and the comment…
app/controllers/application_controller.rb: * [ 8] fix me
Rails defines several other annotation types for you
rake notes # Enumerate all annotations rake notes:fixme # Enumerate all FIXME annotations rake notes:optimize # Enumerate all OPTIMIZE annotations rake notes:todo # Enumerate all TODO annotations
And you also may define your own
# SEAN: please rewrite this method to query only chunky bacon
you may find all instances of “SEAN” by running
rake notes:custom ANNOTATION=SEAN
Rake DB Everything, Dump, Destroy, Create, Load
I’m a big fan of the yaml_db plugin. But I don’t like running rake db:data:load, only to find that my db columns mismatch my model attributes, thus aborting the data import task. To quickly add/remove columns/attributes from a model and rebuild the database with previous db info, I wrote this simple rake task. It saves model records as yaml in db/seandb.yml, and reloads them in the same task but with the db rebuilt. I nest the save method in begin/rescue so that if there are any conflicts the task will continue.
This biggest challenge was to get a list of all the active record models in the Rails app. This problem has been posted a lot and I didn’t find an easy solution. For now, I just look in the app/models directory and ‘classify’ and ‘constantize’ the file name. This will load the model so that I can iterate over all the active record subclasses and call the appropriate Model.find(:all) method. I could maybe do the same w/ all files in the Rails.configuration.load_paths, but my models are, at least for now, under app/models. Plugin models are loaded and available from the rake task if you require the :environment.
It’s as simple as running
rake db:everything
SAVEDB = "#{RAILS_ROOT}/db/seandb.yml"
namespace :db do
task :everything => [:environment, :spit, :drop, :create, :migrate, :populate] do
desc "spit out model records as yaml, rebuild the database and repopulate the db"
end
task :spit do
Dir["#{RAILS_ROOT}/app/models/*"].each {|file| (File.basename(file,".*").classify.constantize)}
File.open(SAVEDB, "w") do |f|
ActiveRecord::Base.send(:subclasses).each do |model|
begin
model.find(:all).each do |record|
f.write(record.to_yaml)
print "\twrote #{record.class}\n"
end
rescue
end
end
end
end
task :populate do
File.open( SAVEDB ) do |yf|
YAML.each_document( yf ) do |ydoc|
begin
m = ydoc.clone
m.save
p "...saved #{m.id}"
rescue
end
end
end
end
end


