How do I override rake tasks for a custom database adapter?
Asked Answered
P

2

7

I've written a custom database adapter that works correctly and effectively when a rails server is running. I would now like to add the usual rake task definitions for creating, dropping and migrating the database.

I would like to implement:

db:[drop|create|migrate]

How do I package these definitions with my gem so that they override the default ones for anyone who uses the gem?

I looked through the source of other adapters but all the rake task logic appears to be baked into active_record itself, each task just switches on the adapter name.

Priddy answered 1/6, 2011 at 18:30 Comment(3)
Are you sure you want to override them? It would be confusing if yours didn't work exactly like the standard ones and if yours do work exactly like the standard ones then the AR versions should be fine.Maestricht
@mu yes I'm quite sure. /activerecord/railties/databases.rake just delegates to methods it defines (e.g. drop_database, create_database) and those methods switch on known connection adapters (mysql, sqlite, postgressql, etc). If the custom adapter is not named one of the provided one's then you have no way to call your own implementations of drop and create.Priddy
Wow, unbelievable. I wasn't expecting ActiveRecord to be quite that stupid and poorly designed, I would have thought that all that stuff would have been pushed down into the database driver. I take it that you're trying to add an Oracle driver or something like that?Maestricht
T
14

This is possible with:

# somewhere in your gem's tasks
Rake::Task['db:create'].clear

# then re-define
namespace 'db' do
  task 'create' do
    # ...
  end
end

When Take::Task#[] can't resolve a task it will fail. If your tasks sometimes exists, you might want to:

task_exists = Rake.application.tasks.any? { |t| t.name == 'db:create' }
Rake::Task['db:create'].clear if task_exists

If you want to add tasks to an existing rake task, use enhance.

Rake::Task['db:create'].enhance do
  Rake::Task['db:after_create'].invoke
end
Trodden answered 16/6, 2011 at 23:16 Comment(0)
E
3

You can write

Rake::Task['db:create'].clear

to delete the original task before redefining it. Also check out Overriding rails' default rake tasks

Etherize answered 4/4, 2014 at 20:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.