Using Rails migrations with JRuby

Hi

We have a java project where we’re using Rails migrations to handle
database evolution. We’re not using Rails for anything else (in this
project) so we have done some standalone scripts that uses irb (we
have a migration console) and ActiveRecord/Migrations.

What I would like to do now is to change to use JRuby instead. This is
for several reasons:

  • I want to include necessary jars (and possibly other stuff) in our
    VCS in order to not require extra installations apart from java (and
    ant)
  • I want to control it better from ant
  • I want to run the migrations from inside our server if we notice
    that the environment isn’t setup correctly
  • I want to be able to use HSQLDB/H2 for development environments and
    demo environments (where we want as little setup overhead as possible)
  • It harmonzies better with the rest of our environment

I’m fairly new to JRuby (not standard Ruby and Rails though) and would
love to have some pointers on where to start to fix this.

/Marcus

ps. I do believe that JRuby rocks! :slight_smile:


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

I’m not sure what problem you’re running into here. Have you looked
at the JRuby on Rails tutorials, they all describe what changes you
need to make to your database adapter for the JDBC version of Mysql/
Postgres/H2/whatever database. That’s really the only big change you
need to make. I have used ActiveRecord outside of Rails with JRuby
and can attest that it works just fine.

David K.

On May 13, 2009, at 4:58 AM, Marcus B. wrote:

  • I want to include necessary jars (and possibly other stuff) in our
    love to have some pointers on where to start to fix this.

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Well, I’ve gotten jruby to work internally in our application together
with our old activerecord/migrations hack (when I installed the
correct version of AR in the projects version of jruby, 1.15.6 to be
exact). Our migrations work perfectly using the normal mysql adapter.

I then tried to get hsqldb to work. I first installed the jdbc
AR-adapter and then changed the database config to something like:

database:
adapter: jdbc
username: sa
password:
driver: org.hsqldb.jdbcDriver
url: jdbc:hsqldb:db/dev.db

That doesn’t work perfect however. The error I get is:

~/ws/dreampark>jruby/bin/jruby db/migrate_console.rb
=== Migration Console ===
/Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/1.8/gems/activerecord-1.15.6/lib/active_record/connection_adapters/abstract/connection_specification.rb:210:in
`establish_connection’:ActiveRecord::AdapterNotFound: database
configuration specifies nonexistent jdbc adapter

I have installed the adapter as far as I know:

ls jruby/lib/ruby/gems/1.8/gems/
ActiveRecord-JDBC-0.5
activerecord-jdbcmysql-adapter-0.9.1 rake-0.8.4
CVS activesupport-1.4.4
rspec-1.2.6
activerecord-1.15.6 activesupport-2.3.2
sources-0.0.1
activerecord-2.3.2 jdbc-mysql-5.0.4
activerecord-jdbc-adapter-0.9.1 mysql-2.7

Anyone have any ideas on what might be wrong?

/Marcus

On Mon, May 18, 2009 at 8:50 PM, David K. [email protected]
wrote:

  • I want to include necessary jars (and possibly other stuff) in our
    love to have some pointers on where to start to fix this.

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Thu, May 28, 2009 at 7:40 PM, Charles Oliver N.
[email protected] wrote:

  • What version of JRuby?

~/ws/dreampark>jruby/bin/jruby -v
jruby 1.3.0RC1 (ruby 1.8.6p287) (2009-05-01 9cbadb8) (Java HotSpot™
64-Bit Server VM 1.6.0_07) [x86_64-java]

On a mac.

Why is it that your migrations require such an old AR version to run?

We could probably patch up our code to work with later versions. The
reason that we’re using such an old version is that we wanted
something similar to Rails Engines (that was really new and mostly not
working at the time and didn’t work anyway for our environment) but
for migrations and, on top of it, in an application that before this
was totally void of anything ruby, rake or rails. So we hacked up some
code that did our module stuff in an irb environment and also did some
monkey patching to get ID generation using bigints (hey, it’s a java
project, we’re using hibernate with long ids as everybode else!) and a
couple of things more. These monkey patches seems to be uncompatible
with later versions.

The monkey patching parts aren’t that many so if it’s only those parts
that that needs to be touched up (about 50 lines of code of around
500) then it’s no real biggie although it’s a hack that nobody really
want’s to revisit…

  • HSQL has not had a lot of attention, certainly not as much as MySQL and
    friends. It can probably be whipped into shape, but we will need some help
    and patience to get it there.

Maybe we should try to make it work using the mysql driver first on
the new version and then try to make hsql work after that?

/Marcus


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Marcus B. wrote:

project, we’re using hibernate with long ids as everybode else!) and a

and patience to get it there.

Maybe we should try to make it work using the mysql driver first on
the new version and then try to make hsql work after that?

That’s probably the best course of action. We don’t have resources to
support older versions of ActiveRecord, so if you can upgrade it we’d be
more likely to help. And of course if you upgrade, you’ll be on more
recent AR logic that we know about, so helping would be easier.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Marcus B. wrote:

Well, I’ve gotten jruby to work internally in our application together
with our old activerecord/migrations hack (when I installed the
correct version of AR in the projects version of jruby, 1.15.6 to be
exact). Our migrations work perfectly using the normal mysql adapter.

I then tried to get hsqldb to work. I first installed the jdbc
AR-adapter and then changed the database config to something like:

Ok, a few things:

  • What version of JRuby?
  • HSQL has not had a lot of attention, certainly not as much as MySQL
    and friends. It can probably be whipped into shape, but we will need
    some help and patience to get it there.
  • Most of the work on improving ActiveRecord for JDBC has been done in
    the 2.x timeframe, so I’d be very surprised if earlier versions of AR
    worked well. We only have so many hands :slight_smile:

Why is it that your migrations require such an old AR version to run?

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Thu, May 28, 2009 at 9:52 PM, Charles Oliver N.
[email protected] wrote:

Maybe we should try to make it work using the mysql driver first on
the new version and then try to make hsql work after that?

That’s probably the best course of action. We don’t have resources to
support older versions of ActiveRecord, so if you can upgrade it we’d be
more likely to help. And of course if you upgrade, you’ll be on more recent
AR logic that we know about, so helping would be easier.

After some goofing around I’ve actually got it almost working. The
table definition parts seems to work (at least I have lots of tables
in the db :). What doesn’t work is actually something we haven’t
touched (I think anyway). From irb session (the migrations failed in
the exact same way):

irb(main):023:0> class BoxType < ActiveRecord::Base
irb(main):024:1> set_table_name “boxtype”
irb(main):025:1> set_primary_key “uid”
irb(main):026:1> end
=> nil
irb(main):027:0> BoxType
=> BoxType(uid: integer, code: string, name: string)
irb(main):028:0> BoxType.create(:code => “pc”, :name => “pc”)
TypeError: can’t dup NilClass
from
/Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2189:in
scoped_methods' from /Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2193:in current_scoped_methods’
from
/Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2176:in
scoped?' from /Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:2440:in initialize’
from
/Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:726:in
`create’
from (irb):29
irb(main):029:0>

What is that about?

/Marcus


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Would an explicit require help?

require ‘box_type’

Or perhaps

BoxType.reset_column_information

Though, I think “good practices” say to not rely on models in the
migrations. Migration #1 might need model version 1, while Migration
#82 might need model version 7. If you’re migrating from scratch to
#82 in one go, the assumptions about the model may not be correct.

ie, Migration #1 might use a method that got removed/changed by the
time you’re trying to re-run Migration #1 to get up to #82.

In that case, you have to checkout historical versions where the
migrations match the models, and do several partial migrations from #1
to #82.

-Bob

On May 29, 2009, at 8:06 AM, Marcus B. wrote:

set_primary_key “uid”
end
set_table_name “boxtype”
This may be more of a Rails question but does anyone have any

Maybe we should try to make it work using the mysql driver first on

=> nil
from /Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

I actually got it working now (both mysql and H2). The only problem
I’ve got left is that Rails seems to have changed when and how it
loads metadata from the database. The problem I posted about yesterday
with the “cannot dup NilClass” seems to be related to when the
AR-classes are defined. In our old migrations we have defined
AR-classes first and then run the actual migration that creates the
table in question. Example:

class BoxType < ActiveRecord::Base
set_table_name “boxtype”
set_primary_key “uid”
end

class InitialSchema < ActiveRecord::Migration
def self.up
create_table …
BoxType.create([{ … }, { … }])
end
def self.down

end
end

Doesn’t work anymore (did before)

This does however work:

class InitialSchema < ActiveRecord::Migration
def self.up
create_table …
module_eval <<-EOS
class BoxType < ActiveRecord::Base
set_table_name “boxtype”
set_primary_key “uid”
end
EOS
BoxType.create([{ … }, { … }])
end
def self.down

end
end

This may be more of a Rails question but does anyone have any
suggestions on how to solve this without having to rewrite > 100
migration files?

/Marcus

On Thu, May 28, 2009 at 10:44 PM, Marcus B.
[email protected] wrote:

irb(main):026:1> end
`scoped?’


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Fri, May 29, 2009 at 3:03 PM, Bob McWhirter [email protected] wrote:

Would an explicit require help?

   require 'box_type'

The thing is that we do the AR class defintions inside the migration
file to get around the issue you describe below. We don’t use any real
AR-classes in this case both just because they might break with
different versions of the migrations (we went into that trap in
another project before this one).

Or perhaps

   BoxType.reset_column_information

Didn’t help.

Though, I think “good practices” say to not rely on models in the
migrations. Migration #1 might need model version 1, while Migration #82
might need model version 7. If you’re migrating from scratch to #82 in one
go, the assumptions about the model may not be correct.

ie, Migration #1 might use a method that got removed/changed by the time
you’re trying to re-run Migration #1 to get up to #82.

In that case, you have to checkout historical versions where the migrations
match the models, and do several partial migrations from #1 to #82.

Note that we only use the AR classes because we’re a little bit lazy.
It’s normally easier to use AR to do some quick find() or updates than
to write all that SQL. Since we don’t define anything in the
AR-classes except from table name and primary key I think we should be
safe from the scenario you describe (and we even describe the
AR-classes in each migration file where they are used which leads to
that we in some cases have the same AR definitions in multiple
migration files)

/Marcus

AR-classes first and then run the actual migration that creates the
BoxType.create([{ … }, { … }])
class InitialSchema < ActiveRecord::Migration
def self.down
On Thu, May 28, 2009 at 10:44 PM, Marcus B.

more likely to help. And of course if you upgrade, you’ll be on more
irb(main):023:0> class BoxType < ActiveRecord::Base
`scoped_methods’
/Users/marcusbristav/ws/dreampark/jruby/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:726:in
To unsubscribe from this list, please visit:


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email