2012/12/29

[rails]レガシーなDBにつなぐ際のRakeタスク

Railsアプリを開発する際に、レガシーなDBを扱う場合を考えます。
この場合のアプリケーションはDBのスキーマ情報を定義しないため、RSpecを導入してrake specを実行した場合、 schema.rbが空であるため、db系のrakeタスクが動かずに、エラーとなります。
これを回避するために、db系のrakeタスクをアプリケーションで上書きして、 何もしないタスクに置き換えることができます。

アプリケーション定義Rakeタスクファイルとして、

{Rails.root}/lib/tasks/db.rake
を作成し、次のように実装します。

module Rake::TaskManager
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

Rake.application.remove_task "db:create"
Rake.application.remove_task "db:drop"
Rake.application.remove_task "db:fixtures:load"
Rake.application.remove_task "db:migrate"
Rake.application.remove_task "db:migrate:status"
Rake.application.remove_task "db:rollback"
Rake.application.remove_task "db:schema:dump"
Rake.application.remove_task "db:schema:load"
Rake.application.remove_task "db:seed"
Rake.application.remove_task "db:setup"
Rake.application.remove_task "db:structure:dump"
Rake.application.remove_task "db:test:prepare"

namespace :db do
  desc "do nothing."
  task :create => :environment do
    puts "This task does nothing."
  end

  : 以下、全てのタスクを空に。
end

rake -Tを実行すると、db系タスクが上書きできていることが確認できます。 これで、レガシーDBを扱うアプリケーションでも、DBを変更する危険もなく、 RSpecもスムーズに実行することができます。