かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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