JavaからFixturesを使ってみる - Rubyコードを使わずJavaコードのみで実現する編
といっても、evalScriptletを使っているので、少しはRubyコード出てきますが。。
FixturesをRails外で使ってみるのRubyコードをJavaに移植するイメージ。
import org.jruby.*; import org.jruby.runtime.*; import org.jruby.runtime.builtin.*; public class CallRuby { public static void main(String[] args) throws Exception { // JRuby環境を取得 Ruby runtime = Ruby.newInstance(); ThreadContext context = runtime.getCurrentContext(); // 必要なgemをrequire runtime.evalScriptlet("require 'rubygems'"); runtime.evalScriptlet("require 'active_record'"); runtime.evalScriptlet("require 'active_record/fixtures'"); // runtime.getClass("ActiveRecord::Base")は不可 // ActiveRecordモジュールを取得 RubyModule activeRecordModule = runtime.getModule("ActiveRecord"); // ActiveRecord::Baseクラスを取得 RubyClass activeRecordBaseClass = activeRecordModule.getClass("Base"); // コネクションを確立 RubyHash arg = new RubyHash(runtime); arg.put(RubySymbol.newSymbol(runtime, "adapter"), "jdbcderby"); arg.put(RubySymbol.newSymbol(runtime, "database"), "hoge"); activeRecordBaseClass.callMethod(context, "establish_connection", arg); // Fixturesクラスを取得 System.out.println("insert"); RubyClass fixturesClass = runtime.getClass("Fixtures"); RubyString arg1 = runtime.newString("data"); RubyArray arg2 = runtime.newArray(); arg2.add("PEOPLE"); IRubyObject[] arguments = {arg1, arg2}; // Fixtures#create_fixtures呼び出し IRubyObject fixturesObj = fixturesClass.callMethod(context, "create_fixtures", arguments); // Personクラスを定義 //RubyClass personClass = runtime.defineClass("Person", activeRecordBaseClass, ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR); runtime.evalScriptlet("class Person < ActiveRecord::Base\nend"); RubyClass personClass = runtime.getClass("Person"); // 全レコードを表示 System.out.println("select all"); showAllPersons(runtime, context, personClass); // Fixtures#delete_existing_fixtures呼び出し System.out.println("delete"); fixturesObj.callMethod(context, "delete_existing_fixtures"); // 全レコードを表示 System.out.println("select all"); showAllPersons(runtime, context, personClass); System.out.println("finish"); } /** * PEOPLEテーブルの全レコードを表示 */ private static void showAllPersons(Ruby runtime, ThreadContext context, RubyClass personClass) { RubySymbol arg1 = RubySymbol.newSymbol(runtime, "all"); RubyHash arg2 = new RubyHash(runtime); arg2.put(RubySymbol.newSymbol(runtime, "order"), "ID"); IRubyObject[] arguments = {arg1, arg2}; // Person#find呼び出し IRubyObject personObjArray = personClass.callMethod(context, "find", arguments); RubyArray persons = (RubyArray)personObjArray; for(int i=0; i<RubyNumeric.num2int(persons.length()); i++) { RubyObject personObj = (RubyObject)persons.get(i); IRubyObject id = personObj.callMethod(context, "id"); IRubyObject name = personObj.callMethod(context, "name"); System.out.println(id + "/" + name); } } }
というわけで、なんかうまく動かないところは、evalScriptletに逃げるという策を使えば、
わりとできてしまうことが分かりました。
JRubyのAPIって、JavaのリフレクションAPIをたたくのに似てますね。