Skip to content

Instantly share code, notes, and snippets.

@schickling
Last active November 5, 2024 09:14
Show Gist options
  • Save schickling/6762581 to your computer and use it in GitHub Desktop.
Save schickling/6762581 to your computer and use it in GitHub Desktop.
Activerecord without Rails
# config/database.yml
host: 'localhost'
adapter: 'postgresql'
encoding: utf-8
database: 'test'
require "active_record"
namespace :db do
db_config = YAML::load(File.open('config/database.yml'))
db_config_admin = db_config.merge({'database' => 'postgres', 'schema_search_path' => 'public'})
desc "Create the database"
task :create do
ActiveRecord::Base.establish_connection(db_config_admin)
ActiveRecord::Base.connection.create_database(db_config["database"])
puts "Database created."
end
desc "Migrate the database"
task :migrate do
ActiveRecord::Base.establish_connection(db_config)
ActiveRecord::Migrator.migrate("db/migrate/")
Rake::Task["db:schema"].invoke
puts "Database migrated."
end
desc "Drop the database"
task :drop do
ActiveRecord::Base.establish_connection(db_config_admin)
ActiveRecord::Base.connection.drop_database(db_config["database"])
puts "Database deleted."
end
desc "Reset the database"
task :reset => [:drop, :create, :migrate]
desc 'Create a db/schema.rb file that is portable against any DB supported by AR'
task :schema do
ActiveRecord::Base.establish_connection(db_config)
require 'active_record/schema_dumper'
filename = "db/schema.rb"
File.open(filename, "w:utf-8") do |file|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
end
end
end
namespace :g do
desc "Generate migration"
task :migration do
name = ARGV[1] || raise("Specify name: rake g:migration your_migration")
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
path = File.expand_path("../db/migrate/#{timestamp}_#{name}.rb", __FILE__)
migration_class = name.split("_").map(&:capitalize).join
File.open(path, 'w') do |file|
file.write <<-EOF
class #{migration_class} < ActiveRecord::Migration
def self.up
end
def self.down
end
end
EOF
end
puts "Migration #{path} created"
abort # needed stop other tasks
end
end

Usage

$ rake db:create # create the db
$ rake db:migrate # run migrations
$ rake db:drop # delete the db
$ rake db:reset # combination of the upper three
$ rake db:schema # creates a schema file of the current database
$ rake g:migration your_migration # generates a new migration file
@jovanmaric
Copy link

jovanmaric commented Mar 27, 2020

The following worked for me when using a db/migrate directory like in rails. ActiveRecord::Tasks::DatabaseTasks is an option too, but the default values have to be changed as it defaults to requiring the Rails object.

def establish_connection
  ActiveRecord::Base.establish_connection(
    {
      adapter: 'postgresql',
      encoding: 'unicode',
      host: 'localhost',
      port: 5432,
      pool: 10,
      username: 'postgres',
      password: 'postgres',
      database: 'your_database_name'
    }
  )
end

def clear_all_connections
  ActiveRecord::Base.clear_all_connections!
end

def generate_schema
  ActiveRecord::Base.connection_pool.with_connection do |connection|
    File.open('db/schema.rb', 'w') do |file|
      ActiveRecord::SchemaDumper.dump(connection, file)
    end
  end
end

def migrate_db
  establish_connection

  ActiveRecord::Base.connection_pool.with_connection do |connection|
    connection.migration_context.migrate
  end

  generate_schema

  clear_all_connections
end

@diegodurs
Copy link

diegodurs commented Jul 15, 2020

This two fixes made it for me with active record 6.0:

namespace :db do
  # ...
 desc "Migrate the database"
  task :migrate do
    ActiveRecord::Base.establish_connection(db_config)
    ActiveRecord::Base.connection.migration_context.migrate

    Rake::Task["db:schema"].invoke
    puts "Database migrated."
  end

  desc "Rollback the last migration"
  task :rollback do
    step = ENV["STEP"] ? ENV["STEP"].to_i : 1

    ActiveRecord::Base.establish_connection(db_config)
    ActiveRecord::Base.connection.migration_context.rollback(step)

    Rake::Task["db:schema"].invoke
    puts "Database rollback."
  end
  # ...
end

namespace :g do
  desc "Generate migration"
  task :migration do
    name = ARGV[1] || raise("Specify name: rake g:migration your_migration")
    timestamp = Time.now.strftime("%Y%m%d%H%M%S")
    path = File.expand_path("../db/migrate/#{timestamp}_#{name}.rb", __FILE__)
    migration_class = name.split("_").map(&:capitalize).join

    File.open(path, 'w') do |file|
      file.write <<-EOF
class #{migration_class} < ActiveRecord::Migration[6.0]
  def self.up
  end
  def self.down
  end
end
      EOF
    end

    puts "Migration #{path} created"
    abort # needed stop other tasks
  end
end

@lain0
Copy link

lain0 commented Apr 3, 2021

is it better to load Rake tasks instead? like in this gist:

require 'bundler/setup'

require 'active_record'

include ActiveRecord::Tasks

db_dir = File.expand_path('../db', __FILE__)
config_dir = File.expand_path('../config', __FILE__)

DatabaseTasks.env = 'development'
DatabaseTasks.db_dir = db_dir
DatabaseTasks.database_configuration = YAML.load(File.read(File.join(config_dir, 'database.yml')))
DatabaseTasks.migrations_paths = File.join(db_dir, 'migrate')

task :environment do
  ActiveRecord::Base.establish_connection(
    {
      adapter: 'postgresql',
      encoding: 'unicode',
      host: 'localhost',
      port: 5432,
      pool: 10,
      username: 'postgres',
      password: 'postgres',
      database: 'your_database_name'
    }
  )
  # require_relative './config/environment'
  # ActiveRecord::Base.configurations = DatabaseTasks.database_configuration
  # ActiveRecord::Base.establish_connection DatabaseTasks.env
end

load 'active_record/railties/databases.rake'

@Shigawire
Copy link

@Iaian0 came here to confirm. Loading the default tasks from ActiveRecord works just fine:

load 'active_record/railties/databases.rake'

@mwitkowskiaudi
Copy link

awesome...thank you for this 👍

@krisleech
Copy link

It seems to need a Rails constant with ActiveRecord 7.x:

rake db:create
-- create_table(:issues_issues, {:id=>:uuid, :force=>true})
   -> 0.0034s
uninitialized constant primary::Rails

        @root ||= Rails.root
                  ^^^^^

@lain0
Copy link

lain0 commented Sep 2, 2024

With rails.7.2.1 (activerecord 7.2.0) it works like as with rails6 just fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment