[Awesome Ruby Gem] Use annotate gem to annotate Rails classes with schema and routes info

Annotate (aka AnnotateModels)

The Annotate (aka AnnotateModels) gem annotating Rails classes with schema and routes info by adding a comment summarizing the current schema to the top or bottom of each of your…

  • ActiveRecord models

  • Fixture files

  • Tests and Specs

  • Object Daddy exemplars

  • Machinist blueprints

  • Fabrication fabricators

  • Thoughtbot’s factory_bot factories, i.e. the (spec|test)/factories/_factory.rb files

  • routes.rb file (for Rails projects)

The schema comment looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# == Schema Info
#
# Table name: line_items
#
# id :integer(11) not null, primary key
# quantity :integer(11) not null
# product_id :integer(11) not null
# unit_price :float
# order_id :integer(11)
#

class LineItem < ActiveRecord::Base
belongs_to :product
. . .

Installation

You can install it as a gem:

1
$ gem install annotate

or add it into a Gemfile (Bundler):

1
2
3
4
5
6
7
8
# Gemfile

# Put gems used only for development or testing in the appropriate group in the Gemfile
group :development do
# ctran/annotate_models: Annotate Rails classes with schema and routes info
# https://github.com/ctran/annotate_models
gem 'annotate', '3.1.1'
end

Then, run bundle install.

1
$ bundle install

Usage

(If you used the Gemfile install, prefix the below commands with bundle exec.)

Usage in Rails

To annotate all your models, tests, fixtures, and factories:

1
2
3
$ cd /path/to/app

$ annotate

Configuration

If you want to always skip annotations on a particular model, add this string anywhere in the file:

1
# -*- SkipSchemaAnnotations

Configuration in Rails

To generate a configuration file (in the form of a .rake file), to set default options:

1
2
3
4
$ rails g annotate:install
Running via Spring preloader in process 6523
create lib/tasks/auto_annotate_models.rake

Edit this file lib/tasks/auto_annotate_models.rake to control things like output format, where annotations are added (top or bottom of file), and in which artifacts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# cat lib/tasks/auto_annotate_models.rake

# NOTE: only doing this in development as some production environments (Heroku)
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
# NOTE: to have a dev-mode tool do its thing in production.
if Rails.env.development?
require 'annotate'
task :set_annotation_options do
# You can override any of these by setting an environment variable of the
# same name.
Annotate.set_defaults(
'routes' => 'false',
'position_in_routes' => 'before',
'position_in_class' => 'before',
'position_in_test' => 'before',
'position_in_fixture' => 'before',
'position_in_factory' => 'before',
'position_in_serializer' => 'before',
'show_foreign_keys' => 'true',
'show_complete_foreign_keys' => 'false',
'show_indexes' => 'true',
'simple_indexes' => 'false',
'model_dir' => 'app/models',
'root_dir' => '',
'include_version' => 'false',
'require' => '',
'exclude_tests' => 'false',
'exclude_fixtures' => 'false',
'exclude_factories' => 'false',
'exclude_serializers' => 'false',
'exclude_scaffolds' => 'true',
'exclude_controllers' => 'true',
'exclude_helpers' => 'true',
'exclude_sti_subclasses' => 'false',
'ignore_model_sub_dir' => 'false',
'ignore_columns' => nil,
'ignore_routes' => nil,
'ignore_unknown_models' => 'false',
'hide_limit_column_types' => 'integer,bigint,boolean',
'hide_default_column_types' => 'json,jsonb,hstore',
'skip_on_db_migrate' => 'false',
'format_bare' => 'true',
'format_rdoc' => 'false',
'format_markdown' => 'false',
'sort' => 'false',
'force' => 'false',
'frozen' => 'false',
'classified_sort' => 'true',
'trace' => 'false',
'wrapper_open' => nil,
'wrapper_close' => nil,
'with_comment' => 'true'
)
end

Annotate.load_tasks
end

Markdown

The format produced is actually MultiMarkdown, making use of the syntax extension for tables. It’s recommended you use kramdown as your parser if you want to use this format. If you’re using yard to generate documentation, specify a format of markdown with kramdown as the provider by adding this to your .yardopts file:

1
2
3
4
# cat .yardopts

--markup markdown
--markup-provider kramdown

Be sure to add this to your Gemfile as well:

1
gem 'kramdown', groups => [:development], require => false

WARNING

Don’t add text after an automatically-created comment block. This tool will blow away the initial/final comment block in your models if it looks like it was previously added by this gem.

References

[1] ctran/annotate_models: Annotate Rails classes with schema and routes info - https://github.com/ctran/annotate_models

[2] pinnymz/migration_comments: Comments for your migrations - https://github.com/pinnymz/migration_comments