When will Active Record be really Rails-independent? Concern about migrations

Hi,

I found a special ActiveRecord case which messes a bit one requirement. I have two applications sharing the same DB. For this reason we found wise to share the DB mapping logic among both applications, namely, our activerecord models. After extracting them into a gem and bundling them into the two applications, everything went well.

Now, we found out it would also be wise to share the migrations, schema, config, etc., maybe “delegate” such rake tasks as create migration and schema dump to that shared repo, which would contain also this part of the logic. Thing is, the use of the Rails class throughout all the rake tasks concerning migrations make that impossible. Specially the load_config rake task, which is apparently run before each and every rake task. This one basically overwrites any rewrite I might have had done on the ActiveRecord::Migrator.migration_paths with the local ‘db/migrate’ folder. Which in my case would be empty in both application trees and full on the shared repo. Because of that, I can’t wisely set a new migration path without entering a world of hurt and non-stop monkey patch. Which I’ll avoid by now. But basically, that load_config rake_task is messing up my plans.

Another concern is the use of the Rails class itself. It could be the case that I would be talking about two rails applications, but one of them happens to be Sinatra, which doesn’t own (or shouldn’t own) any Rails class. I’ve seen how they extended the migrations part for their version of active record. Also a very limiting solution. So, I guess the solution will probably not come from the frameworks readapting their needs to activerecord, but activerecord having a consistent solution in its box, making it then more extendable for other frameworks (I don’t know how Merb handles this, I might investigate into that).

So, I’d like to open the debate on the subject. Or maybe it has been opened previously. I’d much like to hear your opinion.

Regards, Tiago

Active Record in its own box. The problem is that you want to use something specific to Rail, the database taks.

As you can see in the filename of the database task it should be only loaded when you are using rails and this is why it is inside the railties folder.

You can use migrations without use these tasks, but you will have to make your own task. This is a fair cost to those that don’t want to use the railties infrastructure.

Rafael Mendonça França

http://twitter.com/rafaelfranca https://github.com/rafaelfranca

But that’s the point: I think the rake tasks shouldn’t be Rails-dependent. Since ActiveRecord is dependent from the migration it must run before it is deemed loadable, I think the ORM as an independent ORM should take that into consideration, and make it configurable from the railtie, but not in the databases rake task itself. The migrations are a fundamental part of AR integration, and its rake tasks as well. I mean, when I need to install an extension to run a small subset of migrations for the Sinatra framework, it clearly shows that something could be done a little bit differently in that respect. The rake tasks should be dependent of rake, not Rails (unless there is a very good reason for it, but I don’t see which in this particular example. You know the framework better, maybe you can tell me of an use case where it does make sense).

One question regarding railtie: Can one define in the app configuration more than one migration path, the same way we can do for models/helpers/etc? It would at least mitigate my problems on the Rails side, even though I still think a full AR solution would be best.

Cumprimentos

Installing extensions is not a requirement to get ActiveRecord migrations to work. It might help, but the code required to migrate is pretty straight forward. Rails makes a lot of assumptions about what you want to do with your databases, with different environments (dev/test/etc), seeding, or that you might have migrations in engines that you could run.

I created a simple repo that uses AR without Rails: https://github.com/jwo/ActiveRecord-Without-Rails (postgres specific setup). And if you don’t need to migrate, you can simply connect to an existing database: https://github.com/jwo/dbfu … Setup for these ruby only projects is minimal. You don’t automagically get all the rake tasks that Rails gives you, but in simple ruby projects you might not need them.

  • jwo

I think the answer here that Rafael gave is spot-on. The migration tasks that come with Rails are designed with one database in mind. If you’re operating with multiple databases, then you should create your own migration tasks that migrate your databases for you.

This is interesting. I don’t like AR but I like AR migrations :slight_smile:

So I disabled AR in my Rails project and I'm using Sequel instead.

But I’m using AR migrations to evolve the database scheme. For that I use this great project:

https://github.com/thuss/standalone-migrations

Maybe this could help you with your migrations issues.

Best,
Rodrigo.

Hey Ryan,

  • I’m not working with multiple databases on one application, I’m working with multiple applications (using different ruby frameworks, but all using ActiveRecord) on one database. Actually I’ve worked already with one Rails application on multiple databases, and with some configuration over convention, it is possible.
  • The migration tasks don’t come with Rails, they come with ActiveRecord. Rafael said that the rake tasks are only made available via Railtie, hence they are only automagically usable in a Rails environment. But they belong to ActiveRecord. My concern is only that these AR tasks make use of Rails (and Engine, in this case) variables to make assumptions about migrations directory and such, instead of making it part of the ActiveRecord configuration.

ChuckE,

It is not the best solution but some years ago I worked on a project with that case, one shared database.

To solve the problem of shared migrations, we created a rails application just to run the shared migrations on the database.

That required an extra step before each application deploy, deploy the “shared” application first and after that deploy the “client” applications.

I’m working on another project that required the same solution, a shared database.

Today is more easier because all applications are rails 3 applications, so I created a gem called and did that: http://pastie.org/private/jdxqeuwhu7kncx56aclppg

Using that, you just run rake db:migrate on client applications and everything works fine.

You should be aware from clashing migration versions between client applications because you won’t be noticed about that.

Hey Jwo,

Sorry, I didn’t express myself correctly, I guess. In Sinatra, for one to be able to run/create migrations, one has to install an extension to the AR gem in order for one to access a small subset of the known Rails db tasks.

Hey Gabriel,

That sounds interesting, even though it is not a solution for my particular issue, because it’s not all Rails application. So you have a master application and many slaves. Are the slaves “moving” the migrations to the master app, and then being executed there? and Are the rake tasks from the slave applications calling the same rake tasks in the master application scope? Are the migrations organized only in one place or are they spread across application but run in an orderly fashion timestamp-wise?

ChuckE,

The master application had the only objective to handle the migrations that was shared between the client systems, the application was used just to be able to run rake db:migrate.

The client applications not even knew about that, they are all just expecting the database to be ready all the time.

Maybe your case will be more likely the Nando Vieira case here: Usando modelos ActiveRecord entre projetos diferentes - Nando Vieira (portuguese)

I think will not be a problem to you understand the post if you use a translator :wink:

Hehe, quanto ao tradutor, não será certamente o problema :wink: Obrigado pelo link, vou dar uma olhada então.