0

I am writing a script which I can write in postgresql but would like to write using ActiveRecord. Most of the methods that I would like to use are located in ActiveRecord::ConnectionAdapters::SchemaStatements. Because this is a module how can I use these methods in an ActiveRecord::Base.transaction block. I've already tried calling the methods directly like so:

ActiveRecord::ConnectionAdapters::SchemStatements.drop_table etc.

This doesn't seem to work. Is it even possible to use ActiveRecord like this?

Dan Rubio
  • 4,709
  • 10
  • 49
  • 106
  • Possible duplicate of [How to use ActiveRecord in a ruby script outside Rails?](http://stackoverflow.com/questions/1643875/how-to-use-activerecord-in-a-ruby-script-outside-rails) – Matouš Borák Mar 22 '16 at 18:31
  • Thanks for the response but its not quite what I am looking for. I'm familiar with connecting to a database like how the linked question refers but I need to use methods that are outside of ActiveRecord::Base in order to drop constraints etc. etc. – Dan Rubio Mar 22 '16 at 18:36
  • I see, i think you can still use the methods using `ActiveRecord::Base`, see my answer. – Matouš Borák Mar 22 '16 at 18:57

2 Answers2

0

You need to require active_record, establish a connection to the database and then you can use all the methods through the connection method:

# test.rb
require 'active_record'
require 'pg'

# Change the following to reflect your database settings
ActiveRecord::Base.establish_connection(
  adapter:  'postgresql',
  host:     'localhost',
  database: 'database',
  username: 'username',
  password: 'passwd'
)

puts ActiveRecord::Base.connection.table_exists?('users')

Test run (when the users table indeed exists in my database):

$ ruby test.rb
true
Community
  • 1
  • 1
Matouš Borák
  • 15,606
  • 1
  • 42
  • 53
0

I recently had to do the exact same thing, and, yes, this is possible. I started with a regular Rails project (rails new app) and stripped it down to fit my needs.

My final project structure has only the following folders and files (everything else was deleted):

/app/models/*
/bin/bundle
/bin/rake
/bin/spring
/config/application.rb
/config/boot.rb
/config/database.yml
/config/environment.rb
/config/environments/*
/db/schema.rb
/config.ru
/Gemfile
/Gemfile.lock
/Rakefile

My Gemfile contains:

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '< 5.0.0'

# Use mysql as the database for Active Record
gem 'mysql2' # <-- change this to PostgreSQL

I also have a script app.rb, which I placed at the root of the project:

# ensure that all dependent gems are installed before running
require_relative 'config/boot'

# include dependent libraries
require 'active_record'
require 'active_model'
require 'mysql2' # <-- change this to PostgreSQL
require 'yaml'

# set up environment and connect to the database
environment = ENV['RAILS_ENV'] || 'development'
database = YAML.load_file('config/database.yml')
ActiveRecord::Base.establish_connection database[environment]

# set up logging so you can use $logger.debug or $logger.info anywhere in your code
$logger = Logger.new(File.new("log/#{environment}.log", 'w'))
$logger.level = environment == 'development' ? Logger::DEBUG : Logger::INFO

# include dependent classes in same directory
# this step is optional as the required files can be included as needed
Dir['app/models/*.rb'].each { |file| require_relative file }

Now, suppose you have a model called User defined in /app/models/user.rb as

class User < ActiveRecord::Base

end

You can then write statements like the one below in any file that is included from app.rb:

#execute code as a single transaction
ActiveRecord::Base.transaction do
  user1 = User.create!(first_name: 'Richard', last_name: 'Rahl')
  user2 = User.create!(first_name: 'Kahlan', last_name: 'Amnell')
end

You can even use statements like has_many, belongs_to, etc in your models without any problems.

Hopefully, this will be enough to get you started. Let me know if you need more details.

Vadim
  • 1,916
  • 2
  • 19
  • 39