DEV Community

Cover image for Rails Tasks: exporting database models to a CSV.
Richard MacCaw
Richard MacCaw

Posted on

5 1

Rails Tasks: exporting database models to a CSV.

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 in lib/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 do Rails.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. 🏠

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay