How to use ActiveRecord without Rails.
Rails 無しで ActiveRecord を使う方法。
メモ
- 他の O/R Mapper と違い、基本的にデータベースの定義を書く必要はない
ActiveRecord::Base のサブクラスを定義するだけで OK
プログラム実行後のテーブルへの初回アクセス時に、テーブルの定義を調べている - テーブルの定義などに命名規則がある
この命名規則に従っていない場合少し ruby のコードを書く必要がある - 細かいことをしようとすると直接 SQL を各必要が出てくる
- テーブルのデータへは ActiveRecord::Base のサブクラスを使ってアクセスする
基本的な使い方
- データベースへの接続情報の入った YAML 形式のファイルを作る
- データベース内のテーブル1つにつき、ActiveRecord::Base の sub class を1つ定義する
- YAML ファイルの情報を元にデータベースへの接続を確立する
- ActiveRecord のサブクラスのインスタンスを new で生成したり、find メソッドでレコードを検索して操作する
簡単な使い方
#!/usr/bin/env ruby # definition of 'groups' table #CREATE TABLE IF NOT EXISTS groups ( # id INT(32) UNSIGNED NOT NULL AUTO_INCREMENT, # name VARCHAR(255) NOT NULL, # PRIMARY KEY (id) #) ENGINE=MyISAM; require 'rubygems' require 'activerecord' # automatically map to 'groups' table. class Group < ActiveRecord::Base end # class spec = { :adapter => 'mysql', :encoding => 'utf8', :database => 'messadb_dev', # database name :username => 'messauser', # username for mysql :password => 'messapass', # password for mysql :socket => '/var/run/mysqld/mysqld.sock', } ActiveRecord::Base.establish_connection(spec) # create a record group = Group.new #group.id = 2 group.name = 'christmas town' group.save # find a record by it's name group = Group.find_by_name('christmas town') puts "group.id : #{group.id}" # puts "group.name : #{group.name}" # 'christmas town'
環境例
database: mysql dbnames: 本番用: messadb テスト用: messadb_test 開発用: messadb_dev tables: table1: users table2: groups
ディレクトリ構成例
activerecord-sample/
app/
messa_app.rb # アプリケーション
config/
database.yml # データベースの接続の設定ファイル
db/
setup_dev.mysql # データベースの初期化スクリプト
lib/
messa/
db.rb # Messa::DB::Base, ActiveRecord::Base のサブクラス
db/
user.rb # Messa::DB::Base のサブクラス
group.rb # Messa::DB::Base のサブクラス
必要なもののインストール (Ubuntu 8.10 Intrepid Ibex)
% sudo aptitude install ruby rubygems % sudo gem install activerecord % sudo aptitude install libmysql-ruby
セットアップ&実行例
% cd activerecord-sample % mysql -u root -p mysql> source db/setup_dev.mysql mysql> exit % ruby app/messa_app.rb
app/messa_app.rb
ActiveRecord::Base のサブクラスの Messa::DB::User と Messa::DB::Group をロードする。
require 'messa/db' require 'messa/db/user' require 'messa/db/group'
YAML のデータベース設定ファイルをロードする、それを Messa::DB::Base にセットして、開発用の設定を選択する。
config_file = File.join(MESSA_CONFIG_DIR, 'database.yml') config = YAML::load(ERB.new(IO.read(config_file)).result) Messa::DB::Base.configurations = config Messa::DB::Base.establish_connection(:messadb_development) #Messa::DB::Base.establish_connection(:messadb_test) #Messa::DB::Base.establish_connection(:messadb_production)
新規の group を作成してデータベースに保存。
group = Messa::DB::Group.new group.id = 1 group.name = 'halloween town' group.save
新規のユーザーを作成してデータベースに保存。
user = Messa::DB::User.new user.id = 1 user.group_id = 1 user.name = 'Jack' user.birthday = '1901-10-31' user.save
ユーザーを id を使って取得して表示。
jack = Messa::DB::User.find(1) puts "jack.id : #{jack.id}" # 1 puts "jack.group_id : #{jack.group_id}" # 1 puts "jack.group.name : #{jack.group.name}" # 'halloween town' puts "jack.name : #{jack.name}" # 'Jack' puts "jack.birthday : #{jack.birthday}" # '19001-10-31' puts "jack.age : #{jack.age}" # 107
ソースコード
Download Source Code
- messa_app.rb
-
#/usr/bin/env ruby # -*- coding: utf-8 -*- $LOAD_PATH << File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__)) require 'messa/db' require 'messa/db/user' require 'messa/db/group' require 'date' MESSA_ROOT_DIR = File.expand_path(File.join('..'), File.dirname(__FILE__)) unless defined? MESSA_ROOT_DIR MESSA_CONFIG_DIR = File.join(MESSA_ROOT_DIR, 'config') unless defined? MESSA_CONFIG_DIR config_file = File.join(MESSA_CONFIG_DIR, 'database.yml') config = YAML::load(ERB.new(IO.read(config_file)).result) Messa::DB::Base.configurations = config Messa::DB::Base.establish_connection(:messadb_development) #Messa::DB::Base.establish_connection(:messadb_test) #Messa::DB::Base.establish_connection(:messadb_production) Messa::DB::Group.delete_all Messa::DB::User.delete_all group = Messa::DB::Group.new group.id = 1 group.name = 'halloween town' group.save user = Messa::DB::User.new user.id = 1 user.group_id = 1 user.name = 'Jack' user.birthday = '1901-10-31' user.save user = Messa::DB::User.new #user.id = 2 user.group_id = 1 user.name = 'Sarry' user.birthday = '1997-10-31' user.save puts "today : #{Date.today}" # 2009-01-06 jack = Messa::DB::User.find(1) puts "jack.id : #{jack.id}" # 1 puts "jack.group_id : #{jack.group_id}" # 1 puts "jack.group.name : #{jack.group.name}" # 'halloween town' puts "jack.name : #{jack.name}" # 'Jack' puts "jack.birthday : #{jack.birthday}" # '19001-10-31' puts "jack.age : #{jack.age}" # 107 sarry = Messa::DB::User.find(:first, :conditions => {:name => 'Sarry'}) puts "sarry.id : #{sarry.id}" # puts "sarry.group_id : #{sarry.group_id}" # 1 puts "sarry.group.name : #{jack.group.name}" # 'halloween town' puts "sarry.name : #{sarry.name}" # 'Sarry' puts "sarry.birthday : #{sarry.birthday}" # '1997-10-31' puts "sarry.age : #{sarry.age}" # 11 __END__ today : 2009-01-06 jack.id : 1 jack.group_id : 1 jack.group.name : halloween town jack.name : Jack jack.birthday : 1901-10-31 jack.age : 107 sarry.id : 10 sarry.group_id : 1 sarry.group.name : halloween town sarry.name : Sarry sarry.birthday : 1997-10-31 sarry.age : 11
- database.yml
-
messadb_development: adapter: mysql encoding: utf8 database: messadb_dev username: messauser password: messapass socket: /var/run/mysqld/mysqld.sock messadb_test: adapter: mysql encoding: utf8 database: messadb_test username: messauser password: messapass socket: /var/run/mysqld/mysqld.sock messadb_production: adapter: mysql encoding: utf8 database: messadb username: messauser password: messapass socket: /var/run/mysqld/mysqld.sock
- setup_dev.mysql
-
-- messadb -- % mysql -u root -p -- mysql> create database messadb; -- mysql> source create_tables.mysql -- mysql> exit DROP DATABASE messadb_dev; CREATE DATABASE IF NOT EXISTS messadb_dev DEFAULT CHARACTER SET utf8; GRANT ALL PRIVILEGES ON messadb_dev.* TO messauser@localhost IDENTIFIED BY 'messapass'; use messadb_dev; CREATE TABLE IF NOT EXISTS users ( id INT(32) UNSIGNED NOT NULL AUTO_INCREMENT, group_id INT(32) UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, birthday DATE NULL, added TIMESTAMP NOT NULL DEFAULT 0, updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS groups ( id INT(32) UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, added TIMESTAMP NOT NULL DEFAULT 0, updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINE=MyISAM;
- db.rb
-
# -*- coding: utf-8 -*- require 'rubygems' require 'activerecord' require 'erb' require 'yaml' module Messa module DB class Base < ActiveRecord::Base end # class end # module end # module
- user.rb
-
# -*- coding: utf-8 -*- require 'messa/db' require 'date' module Messa module DB class User < Messa::DB::Base set_table_name 'users' #has_one :group, {:class_name => 'Messa::DB::Group', :foreign_key => 'id'} # this works has_one :group, {:class_name => 'Messa::DB::Group', :foreign_key => 'id', :primary_key => 'group_id'} def age birthday = read_attribute(:birthday) return nil if birthday.nil? today = Date.today age = today.year - birthday.year if (today.month < birthday.month) or (birthday.month == today.month and today.day < birthday.day) age -= 1 end return age end def age=(rhs) raise "Can't set value to age." end end # class end # module end # module
- group.rb
-
# -*- coding: utf-8 -*- require 'messa/db' module Messa module DB class Group < Messa::DB::Base set_table_name 'groups' end # class end # module end # module

