Taking ActiveRecord off the Web
Message from 2022
This post is pretty old! Opinions and technical information in it are almost certainly oudated. Commands and configurations will probably not work. Consider the age of the content before putting any of it into practice.
Standalone console app
So, let’s get this party started with a simple console app that uses ActiveRecord. You can grab the following example from http://brycekerley.net/svn/ar-console/1-simple.rb .
The first things to do are to include rubygems and the activerecord gem (hopefully the machine you’re running the app on has these installed). Once that’s done, go ahead and establish_connection
to the database, sqlite3 in this case.
require 'active_record' ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :dbfile => 'ar-console.db')
Now, I’m going to detour to directly interacting with the database in this case – in Rails, you use migrations to handle working with the data definition SQL (creating, altering, &c. tables). In the absence of that, you can do it by hand.
~/ar-console> sqlite3 ar-console.db SQLite version 3.3.6 Enter ".help" for instructions sqlite> create table names (id integer primary key, firstname varchar(20), lastname varchar(20)); sqlite> .schema CREATE TABLE names (id integer primary key, firstname varchar(20), lastname varchar(20)); sqlite> ^D ~/ar-console>
Now that we have a table to interface with, we have to define a class that aligns with the table and inherits from the ActiveRecord::Base
class. You can require this inline defintion from an external file, or even Dir.glob('some_rails_app/app/models/*.rb').each { |m| require m }
to load all the models for some_rails_app
in one fell swoop. Stay away from this way of integrating with a rails app for now – there’s a much better way.
:firstname=>"Hans", :lastname=>"Gruber") x.save y = Name.new(:firstname=>"John", :lastname=>"McClane") y.save Name.find_all.each { |n| puts n.inspect }end x = Name.new(
Finally, just for grins, we add some movie characters to the database, save them, and show who’s going to be running around Nakatomi Plaza today.
Flexible configuration
What if you want to move the configuration out into a .yml file just like rails? Turns out this isn’t terribly hard - Ruby comes with YAML support, so we can trivially use the same yaml file that Rails does. Adding database.yml
support is nigh-trivial; our only caveat is that if you’re using SQLite you have to remember the path to the database is evaluated from where you execute the Ruby with this setup, seen in http://brycekerley.net/svn/ar-console/2-yamlized.rb.
require 'rubygems' require 'active_record' ActiveRecord::Base.establish_connection(YAML::load_file('database.yml')['development'])
Leeching Off Rails
Sometimes you want a console app to hook right in to Rails, but not serve web pages. As it turns out, we can do this quite cleverly, by loading the Rails environment the same way dispatch.cgi
or script/console
does. As an added bonus, we get to use Rails migrations, models are loaded for us, and so on. You do get to break all your business logic that you implemented as controllers, but you should be using a fat model and a skinny controller for this very reason.
The files we actually care about are boot.rb
and environment.rb
, in your app’s config
directory. Assuming you want your app to live in a subdirectory off of your app’s /
(i.e. next to public
, app
, and vendor
), the incantation you need to establish the connection is as in http://brycekerley.net/svn/ar-console/3-railed.rb:
require File.dirname(__FILE__) + '/../config/environment' ActiveRecord::Base.establish_connection
Coda
To snap up all the examples from this in one fell swoop, svn co http://brycekerley.net/svn/ar-console/ ar-console
. If you’ve got any questions, fire away in the comments.