简体   繁体   中英

Reset DB from Controller/Helper, Ruby on Rails

I've created a demo of my program. The demo is used to present the program to the customers. Before each presentation I want to reset the db, and insert certain data, the actions that I have to do are:

rake db:drop
rake db:setup
rake db:seed:demo

But they are not always me to present it and others do not use the console, so I wanted to put in the settings page the ability to reset via a button.

I tried in this way:

module SettingsHelper
require 'rake'
  def reset
        Rake::Task[db:drop].invoke
        Rake::Task[db:setup].invoke
        Rake::Task[db:seeds:demo].invoke
  end
end

I put in the form:

  <%=button_to "Reset", reset, class:"btn red" %>

But I can not drop the database with the active server ... how can I do?

You cannot drop the database while you have an active connection. Instead what you can do is issue a TRUNCATE command which deletes all rows from the table and reset the ID columns.

Incase you want a more fine grained control over exactly which tables are truncated you can add a class method to the model:

class User < ActiveRecord::Base
  self.truncate!
    self.connection.execute(
      "TRUNCATE TABLE #{ self.table_name };"
    )
    self.connection.reset_pk_sequence!(self.table_name)
  end
end 

But lets DRY it into a module so we don't have to repeat it in all the models that should have this behavior:

# app/models/concerns/resetable.rb
module Resetable
  extend ActiveSupport::Concern
  class_methods do
    def truncate!
      self.connection.execute(
        "TRUNCATE TABLE #{ self.table_name };"
      )
      self.connection.reset_pk_sequence!(self.table_name)
    end
  end
end

# app/models/user.rb
class User < ActiveRecord::Base
  include Resetable
  # ...
end 

 # app/models/book.rb
class Book < ActiveRecord::Base
  include Resetable
  # ...
end 
# ...

You can then reset the data for each model by:

def reset_db
  [User, Book, Thing].each { |model| model.truncate! }
  Rails.application.load_seed
end

If you just want to nuke all the tables you can simply do:

ActiveRecord::Base.connection.tables.each do |t|
  conn = ActiveRecord::Base.connection
  conn.execute("TRUNCATE TABLE #{t} CASCADE;")
  conn.reset_pk_sequence!(t)
end

I pluck some code from following SO answers

You can add something like this in controller

def reset_db
  conn = ActiveRecord::Base.connection
  tables = ActiveRecord::Base.connection.tables
  tables.each { |t| conn.execute("TRUNCATE #{t}") }

  Rails.application.load_seed
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM