かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

ActiveRecord-JDBCお試し

前回は、RDE上でActiveRecord-JDBCを使ったけど、今回はNetBeans6.0M10で試してみた。

下準備

PosgtreSQLのJDBCドライバのjarをNetBeansインストールフォルダの下のruby1/jruby-1.0/libの下にコピー。
これをしないとJDBCドライバが無いってエラーになる。

テーブルの準備

前回と同じテーブル構成じゃつまらないので今回は2つのテーブルを用意した。
DDLは下の通り

create table departments (
  id serial primary key,
  name varchar(50)
);
create table employees (
  id serial primary key,
  name varchar(50),
  department_id int,
  constraint fk_departments 
    foreign key (department_id) references departments(id) 
);

プロジェクトの作成

Ruby Application(Railsじゃないよ)を作成する。
普通に作ると、Rakefile.rbとmain.rbが作られる。
このmain.rbにメインの処理を書いていく。

とりあえずおまじないのrequireと、DBへの接続情報を書く。
main.rbの他にdb.rbというファイルを作って、そこに書いた。

# db.rb
module Db
  require 'rubygems'
  gem 'ActiveRecord-JDBC'
  require 'jdbc_adapter'
  require 'active_record'

  def self.init
    ActiveRecord::Base.establish_connection(
      :adapter => 'jdbc',
      :driver => 'org.postgresql.Driver',
      :url => 'jdbc:postgresql://localhost:5432/activerecord',
      :username => 'postgres',
      :password => 'postgres'
    )
  end
  
  # モジュールが読み込まれたときにDBの接続情報設定
  self.init
end

この続きに、テーブルに対するクラスを作成する。
departmentsテーブルとemployeesテーブルなので、DepartmentクラスとEmployeeクラスを作る。
departmentsテーブルはemployeesを所有(many to one)してるので、その定義も追加する。

# db.rb
module Db
  # 省略
  class Employee < ActiveRecord::Base
    belongs_to :department # departmentsに所有されている
  end
  class Department < ActiveRecord::Base
    has_many :employees # employeesを所有してる
  end
end

準備ができたらDBにデータを入れるコードを書く。

require 'db_conf'

include Db

dept = Department.create(:name => 'Jinji')
dept.employees << Employee.create(:name => 'Tarou')
dept.employees << Employee.create(:name => 'Jirou')

これを実行!!結果は何も出ないので、ちゃんとDBにデータが入ってるかを見るコードを今度は書いてみる。
予定では、Jinjiという部署ができて、そこにTarouくんとJirouくんが所属する手はずだ。
ついでなので、UnitTestで書いてみた。
やってることは、DBからJinjiという名前の部署を探してる。
ついでに従業員のデータもJOINで取るようにしていして、最後に従業員のidでorder byをかけてる。

あとは、とってきたデータが期待値と一致するか確認してる。

$:.unshift File.join(File.dirname(__FILE__),'..','lib')

require 'test/unit'
require 'db_conf'

class TestDb_test < Test::Unit::TestCase
  def test_db_data
    dept = Db::Department.find(
      :all, :conditions => "departments.name = 'Jinji'", 
      :include => :employees, 
      :order => "employees.id").first
    
    assert_equal "Jinji", dept.name, "部署名はJinjiのはず" 
    assert_equal 2, dept.employees.length, "従業員の数は2のはず"
    assert_equal "Tarou", dept.employees[0].name, "Tarouがいるはず"
    assert_equal "Jirou", dept.employees[1].name, "Jirouがいるはず"
  end
end

実行結果は、下の通り。予定通りだ。

Started
.
Finished in 0.783 seconds.

1 tests, 4 assertions, 0 failures, 0 errors