Wednesday, September 06, 2006

ActiveRecord-JDBC 0.2.1 Released!

I told you it would only be a couple days!

ActiveRecord 0.2 has been released. (It's actually 0.2.1 because of a minor Gem glitch)

Ola wraps it up in the link above, but for the record it supports normal AR operations and basic migrations for the following databases:

  • MySQL
  • PostgreSQL
  • Oracle
  • HSQLDB
  • Microsoft SQL Server (except for change_column_default)
  • DB2 (except change_column, change_column_default, rename_column, remove_column,
    add_index, remove_index and rename_table)
  • Derby (except change_column, change_column_default, remove_column, rename_column)
  • FireBird (except change_column_default and rename_column)
Whew! And we really only started getting migrations and additional databases into the mix a week or two ago. Things go very fast when you have JDBC to handle all the heavy lifting!

I'm going to demo the AWDwR2 Depot app running on top of MySQL at Rails, and probably demonstrate one of the other databases Rails doesn't normally support as well (Derby perhaps? or SQL Server if I can get Parallels up before presenting?)

Usage

Ola has a Derby walkthrough with some unusual typos [Update: my mistake, he symlinked stuff like "gem" to "jem" to avoid collisions with MRI], but here's my walkthrough for MySQL in ultra-condensed form:
  1. Install JRuby from trunk or my branch
  2. Build it (not necessary once we get another release out)
    ant clean jar
  3. Set up env vars for JRuby
    export JRUBY_HOME=[jruby dir]
    export PATH=[jruby dir]/bin:$PATH
  4. Install Rails
    gem install rails -y --no-rdoc --no-ri
  5. Install ActiveRecord-JDBC
    gem install activerecord-jdbc --no-rdoc --no-ri
  6. Generate a Rails App
    rails ~/testapp
  7. Go to the app
    cd ~/testapp
  8. Modify database.yml
    development:
    adapter: jdbc
    driver: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost/testapp_development
    username: ...
    password: ...
  9. Modify environment.rb:
    require File.join(File.dirname(__FILE__), 'boot')
    require 'active_record/connection_adapters/jdbc_adapter'
  10. Add driver to CLASSPATH
    export CLASSPATH=$CLASSPATH:mysql.jar
  11. Create a testapp_development database, grants for testapp user, and widgets table in MySQL (use migrations if you like)
  12. Scaffold Widgets CRUD
    jruby script/generate scaffold widget
  13. Start up the server
    jruby script/server
And that's about it. You've got a scaffolded widget page running in JRuby over JDBC to MySQL.

Pretty neat, eh?

Troubleshooting
  • ActiveRecord-JDBC does not install: I had some trouble myself; I think something's up with either RubyForge or with our released gem. You can always download ActiveRecord-JDBC and install it locally, of course.
  • scaffold fails with an error about "nonexistent jdbc adapter": Ensure you've added the require line to environment.rb (hopefully this will be unnecessary in the future)
  • scaffold and script/server terminate without running: Make sure you've successfully installed the ActiveRecord-JDBC gem. The additional require in environment.rb causes Rails scripts to die silently if there are any errors.
  • scaffold fails with the error "cannot convert NilClass into String": Make sure you've correctly specified the driver and url lines in database.yml
What's Next

We're going to continue adding database support, especially if you folks can contribute migrations impls for your database of choice. It's fun and easy!

We've also got a patch under discussion to allow adding JDBC database jars to [RAILS_ROOT]/lib and have the driver pick them up automatically. This could obviously be extended to Rails at large for service client jars, persistence framework jars, and so on. No more CLASSPATH manipulation!

We're hoping to get the Rails guys to include "jdbc" in the list of supported adapters out-of-the-box, so that environment.rb require is not necessary.

We're also going to see if there's a way to abstract out all the DDL code in core Rails, so we can all benefit from the same code.

4 comments:

Kiran said...

hi,
When would JRuby be that could run Rails be available for the public?
Regards
Kiran

Charles Oliver Nutter said...

That's a good question. some, like myself, believe that once all Rails test cases work, JRuby officially "supports" Rails. Others, like myself, think it would also be good to have a large number of real-world apps tested and running under JRuby.

I guess the question is mainly for the community to decide. What would be required for JRuby to "support" Rails?

Kurt said...

I found this note, which appears to be required to get this to work, now.

Yes, the Ruby plugin is updated almost daily, and this bit of configuration changed since I posted the entry. You now need to add the following to your environment.rb:

if RUBY_PLATFORM =~ /java/
require 'rubygems'
RAILS_CONNECTION_ADAPTERS = %w(jdbc)
end
You want to place it right before the line that reads:

Rails::Initializer.run do |config|
Previously this configuration was already set for you, but now you need to add it manually.

Aaron said...

I was getting:

connection_specification.rb:14:in `method_missing':NoMethodError: undefined or inaccessible method `cattr_accessor' for ActiveRecord::Base:Class

Per Headius, I updated my environment.rb so that the added require statement is this shorter version than listed above:

require 'jdbc_adapter'



To: