开发者

Disabling Rails' db:reset task

开发者 https://www.devze.com 2022-12-16 02:28 出处:网络
To avoid an accidental \'rake db:reset\' on our production environments, I was thinking about disabling \'rake db:reset\' and related tasks that drop the database in the production environment.Is ther

To avoid an accidental 'rake db:reset' on our production environments, I was thinking about disabling 'rake db:reset' and related tasks that drop the database in the production environment. Is there an easy way to do this, or do I have to redefine the开发者_运维知识库 rake task?

Is there a better alternative?


In your Rake file you can add

Rake.application.instance_variable_get('@tasks').delete('db:reset')

and the command is not available any more. If you want to disable multiple commands, put it in a remove_task method for readability.

But a better alternative seem to just not type the rake db:reset command, which is not something you'd accidentally type.

Having a nice backup of your (production) database is also a better solution I suppose.


Put this in lib/tasks/db.rake:

if Rails.env == 'production'
  tasks = Rake.application.instance_variable_get '@tasks'
  tasks.delete 'db:reset'
  tasks.delete 'db:drop'
  namespace :db do
    desc 'db:reset not available in this environment'
    task :reset do
      puts 'db:reset has been disabled'
    end
    desc 'db:drop not available in this environment'
    task :drop do
      puts 'db:drop has been disabled'
    end
  end
end

Found here.


Append this on your Rakefile.

namespace :db do
  task :drop => :abort_on_production
end
task :abort_on_production do
  abort "Don't drop production database. aborted. " if Rails.env.production?
end

It also blocks rake db:reset and rake db:migrate:reset because they call db:drop


You could always overwrite the db:reset task with something like this in lib/db.rake:

namespace :db do
  desc 'Resets your database using your migrations for the current environment'
  task :reset do
    if RAILS_ENV == 'production'
      Rake::Task["db:drop"].invoke
      Rake::Task["db:create"].invoke
      Rake::Task["db:migrate"].invoke
    end
  end
end


For the record, We have an application linking into our live production database, we use test login details and from there shard's to out test DB.

The last thing we wanted was for rails to wipe out or database schema when running rspec/unit tests.

use the information is this question and here: Is it possible to get a list of all available rake tasks in a namespace?

I was able to come up with the following solution:

Rake.application.in_namespace(:db){|x|
  x.tasks.map{|t|
    Rake.application.instance_variable_get('@tasks').delete(t.name)
  }
}

This placed into the end of our Rakefile enabled us to remove all db: rake tasks as can be seen here:

[davidc@david-macbookp app1{master}]$ rake -T db
[davidc@david-macbookp app1{master}]$

With a little tweaking this could be done to disable on a per environment basis

Update:

Word of warning doing this for db namespace broke testunit and was required to add the addison:

namespace :db do
  task 'test:prepare' do
  end
end


You could also use the rails_db_protect gem.

You just add the gem and it automatically prevents you from running the following dangerous tasks in production:

db:setup db:reset db:drop db:create db:schema:load

If you have a production environment, like a staging environment, where you want to be able to run these tasks, you can configure the environment to allow it:

ENV['ALLOW_DANGEROUS_TASKS'] = 'true'

There is also the gem rails-safe-tasks which allows more configuration but does not appear to have any tests supporting it.

0

精彩评论

暂无评论...
验证码 换一张
取 消