2011-10-13 36 views
14

Tôi muốn có một nhiệm vụ cào để cắt ngắn tất cả các bảng. Tôi có found one trên internet, nhưng nó được cho là chỉ dành cho Rails 2 và không hoạt động cho Rails 3 (sự cố đang nhận được kết nối cơ sở dữ liệu).Nhiệm vụ Rake để cắt ngắn tất cả các bảng trong Rails 3

rake db:reset không phải là một tùy chọn, bởi vì tôi đang sử dụng PostgreSQL và nó cũng làm giảm người dùng. Do đó di chuyển không thành công. Tôi chỉ muốn xóa dữ liệu.

Các bạn có hiểu không?

+0

Tôi chưa bao giờ thấy người dùng postgres bị xóa khi thực hiện 'db: reset'. Thiết lập của tôi hoàn toàn khác với thiết lập của bạn phải không? – thekingoftruth

Trả lời

32

Tôi đã tìm thấy điều này qua google và sau đó tôi nhận được giải pháp đơn giản hơn nhiều so với giải pháp được chấp thuận, vì vậy tại đây là: Sử dụng đá quý database_cleaner. Đây là các bước.

Trong Gemfile của bạn (thực hiện bó sau khi sửa đổi):

gem 'database_cleaner' # you might want to limit this to the dev and staging group 

Với rằng đá quý tại chỗ, báo cáo kết quả DatabaseCleaner.clean_with :truncation sẽ truncate cơ sở dữ liệu. Thêm nó vào một công việc cào là tầm thường:

# tasks/db/clean.rake 

namespace :db do 

    desc "Truncate all existing data" 
    task :truncate => "db:load_config" do 
    DatabaseCleaner.clean_with :truncation 
    end 

end 

Vậy đó. Bạn cũng có thể sử dụng đường dây DatabaseCleaner.clean_with :truncation bên trong tệp db/seeds.rb của mình trực tiếp để bạn không quên cắt bớt cơ sở dữ liệu trước khi gieo hạt.

+1

Dòng trong tệp hạt giống chính xác là những gì tôi cần –

8

Theo Chris Ledet câu trả lời, điều này trở nên đơn giản hơn nhiều:

ActiveRecord::Base.connection.tables.each do |table| 
    ActiveRecord::Base.connection.execute("TRUNCATE TABLE #{table};") 
end 
+0

Giống như bình luận đầu tiên của tôi cho câu trả lời của Chris. Nhưng cảm ơn! – lzap

3

này sẽ nhận được tất cả các bảng trong cơ sở dữ liệu của bạn, hãy tìm một mô hình kết hợp với bảng đó và gọi # destroy_all.

tables = ActiveRecord::Base.connection.tables 
tables.each do |tbl| 
# "users" => User 
tbl.classify.constantize.destroy_all 
end 
+0

Tôi quan tâm nhiều hơn đến nhiệm vụ Rake - cách triển khai nó. Ví dụ được liên kết chỉ hoạt động với Rails 2.x. Tôi đang cố gắng làm điều đó. – lzap

+0

Sai. Ví dụ này làm việc với Rails 3 và 3.1. Không có gì ngăn cản bạn đặt nó vào một công việc cào. –

+0

Xin lỗi nhưng bạn không cung cấp thông tin về cách tạo kết nối trong Rails 3 (trong tác vụ cào). Một sự khác biệt lớn trong Rails 2 và Rails 3. – lzap

19

Vì vậy, tôi thay đổi nội dung ví dụ liên kết vào đây:

namespace :db do 
    desc "Truncate all existing data" 
    task :truncate => "db:load_config" do 
    begin 
    config = ActiveRecord::Base.configurations[::Rails.env] 
    ActiveRecord::Base.establish_connection 
    case config["adapter"] 
     when "mysql", "postgresql" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("TRUNCATE #{table}") 
     end 
     when "sqlite", "sqlite3" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("DELETE FROM #{table}") 
      ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='#{table}'") 
     end                                
     ActiveRecord::Base.connection.execute("VACUUM") 
    end 
    end 
    end 
end 

dụ này được dựa trên mã dưới đây Chris Ledet của (nhờ) và làm việc với Rails 3.x.

Cảm ơn tất cả các gợi ý.

+0

Làm việc với * Rails 3 *! – lzap

+2

Tôi đã thêm điều này để làm cho nó hoạt động với mysql2: 'ActiveRecord :: Base.connection.execute (" TRUNCATE # {table} ") nếu bảng! =" Schema_migrations "'. Và 'khi 'mysql", "mysql2", "postgresql" 'Nếu không, Rails muốn di chuyển mọi thứ trên một lần nữa. –

+0

Ya chắc chắn cần phải là một 'trừ khi bảng == 'schema_migrations'' trên những dòng cắt ngắn. – nzifnab

6

Bạn luôn có thể chuyển sang phiên bản 0, như vậy:

rake db:migrate VERSION=0 

Bằng cách đó, bạn thậm chí không cần phải cắt ngắn bảng của bạn, và sau đó bạn có thể di chuyển một lần nữa. Điểm duy nhất là bạn cần di chuyển down để hoạt động chính xác.

Giải pháp này hiện hoạt động trong đường ray 3, mặc dù thực tế là các phiên bản dựa trên dấu thời gian.

Giải pháp này là như đã thấy ở đây: https://stackoverflow.com/a/1196822/241367

Ngoài ra, bạn luôn có thể chạy sau, giả sử bạn schema.rb được cập nhật:

rake db:schema:load 

Và như @kikito gợi ý, bạn có thể chạy database_cleaner (đó là những gì cucumberrspec muốn sử dụng giữa các lần kiểm tra) như vậy:

DatabaseCleaner.clean_with :truncation 
+1

Tôi thích ý tưởng sử dụng db: schema: load. Đó là rất sạch sẽ và không chính xác những gì tôi muốn đó là để thiết lập lại cơ sở dữ liệu mà không cần phải thả và tái tạo. –

1

Câu trả lời được đưa ra bởi lzap có một vấn đề cụ thể. Rails muốn chạy lại tất cả các lần di chuyển. Đoạn mã sau được Anthony Alberto đề xuất và nó hoạt động. Phần bổ sung này kiểm tra với bảng schema_migrations

namespace :db do 
    desc "Truncate all existing data" 
    task :truncate => "db:load_config" do 
    begin 
    config = ActiveRecord::Base.configurations[::Rails.env] 
    ActiveRecord::Base.establish_connection 
    case config["adapter"] 
     when "mysql", "postgresql" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("TRUNCATE #{table}") if table != "schema_migrations" 
     end 
     when "sqlite", "sqlite3" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("DELETE FROM #{table}") if table != "schema_migrations" 
      ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='#{table}'") if table != "schema_migrations" 
     end                                
     ActiveRecord::Base.connection.execute("VACUUM") 
    end 
    end 
    end 
end 
Các vấn đề liên quan