Skip to content

Instantly share code, notes, and snippets.

@cristianbica
Last active October 16, 2023 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cristianbica/0c8ff4ddfae045799f1d5891c6f643ae to your computer and use it in GitHub Desktop.
Save cristianbica/0c8ff4ddfae045799f1d5891c6f643ae to your computer and use it in GitHub Desktop.
# You'll need activerecord-import gem installed in your app
class BackupService
def initialize(path: nil)
@path = path || Rails.root.join('tmp', "backup-#{Time.now.to_i}.sqlite")
end
def backup(*scopes)
with_db do
prepare
scopes.each do |scope|
backup_scope(scope)
end
end
true
end
private
def prepare
raise "expecting to use a sqlite3 database connection" unless ActiveRecord::Base.connection.adapter_name == 'SQLite'
Rails.logger.silence do
ActiveRecord::Schema.verbose = false
load(ActiveRecord::Tasks::DatabaseTasks.schema_file)
end
end
def backup_scope(scope)
columns = scope.model.column_names
values = scope.pluck(*columns)
Rails.logger.silence do
scope.model.import(columns, values, validate: false)
end
end
def with_db
begin
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: @path)
yield
ensure
ActiveRecord::Base.connection.disconnect!
ActiveRecord::Base.remove_connection
ActiveRecord::Base.establish_connection
end
end
end
# Usage:
# service = BackupService.new
# service.backup User.all, Company.all
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment