If you just want the code, scroll to the bottom 🥳
Rails has some really nice ways to make a developers life a bit easier. One of them is Rake Tasks. If you have ever executed the command rails c
, or rake db:migrate
, you've already used tasks. Since version 5.0, Rails allows you to call most rake commands with rails
instead.
A bit of background
We needed an automated and simple way to share our database design across the company. A schema file didn't cut it.
ERD gem is a great option to share the high level overview. We use it all the time. It generates a nice PDF showing model associations and attributes (tutorial to come shortly).
But for the nitty gritty details we made a task which exports our database models, attributes and data types to a CSV.
Let's break it down.
- Create a
models_to_csv.rake
file over inlib/tasks
. -
require 'csv'
(built into Rails) to be able to generate CSV's. - Define your task name and list under an optional namespace.
# lib/tasks/models_to_csv.rake
require 'csv'
namespace :custom do
desc 'Generate a CSV with all models, attribute names, and attribute database types'
task models_to_csv: :environment do
end
end
- Load all your database models into memory. Rails does not
eager_load
by default in Rake Tasks. Note for Rails 5 and below, you should doRails.application.eager_load!
- Define where you want to save the CSV.
- Set the column names you want. Three names equals three columns.
- Open up the CSV block and pass in the
headers
.
# lib/tasks/models_to_csv.rake
require 'csv'
namespace :custom do
desc 'Generate a CSV with all models, attribute names, and attribute database types'
task models_to_csv: :environment do
Zeitwerk::Loader.eager_load_all
file = Rails.root.join('public/model_data.csv')
headers = %w[Model Attribute Type].freeze
CSV.open(file, 'w', write_headers: true, headers: headers) do |writer|
end
end
end
Right! Thats the set up done. Next we need to loop through all our model attributes and generate the CSV.
- Iterate over
ActiveRecord::Base.descendants
to get your models. - Skip any models you don't want.
- Iterate over each models attributes.
- Add the model name, attribute and attribute data type to the CSV writer.
- Profit 💸
# lib/tasks/models_to_csv.rake
require 'csv'
namespace :custom do
desc 'Generate a CSV with all models, attribute names, and attribute database types'
task models_to_csv: :environment do
Zeitwerk::Loader.eager_load_all
file = Rails.root.join('public/model_data.csv')
headers = %w[Model Attribute Type].freeze
CSV.open(file, 'w', write_headers: true, headers: headers) do |writer|
ActiveRecord::Base.descendants.each do |model|
next if model.name.starts_with?('ActiveStorage')
model.attribute_names.each do |attribute|
writer << [model.name, attribute, model.columns_hash[attribute].type.to_s]
end
end
end
puts 'CSV generated here -> /public/model_data.csv'
end
end
Awesome. Now all we need to do is run our new task.
rails custom:models_to_csv
PS. We are looking for great Product Engineers over at Generation Home. We are a funded, UK based, pre-launch tech company, tying to create more ways into home ownership. 🏠
Top comments (0)