Seeding a database using the Rails command line

Ruby on Rails có các công cụ rất tốt để tạo cơ sở dữ liệu và nhờ vào những đóng góp của công đồng, có một số gem để thực hiện công việc đó dễ dàng hơn. Bên cạnh việc tạo cơ sở dữ liệu, chúng tôi có các công cụ hữu ích để kiểm tra cơ sở dữ liệu và các cách để tổ chức các hạt dữ liệu quan trọng tốt hơn.

Tạo một ứng dụng mẫu

Hãy bắt đầu gõ rails vào trong một thư mục ứng dụng rails để kiểm tra tất cả các dòng lệnh rẵng có.

rails new sample 
cd sample
rails 

Chúng ta sẽ nhìn thấy các công lệnh phổ biến, và bên dưới là một số lệnh bổ sung. Chúng ta sẽ sử dụng một trong số chứng. Trong thực tế bạn đã sử dụng :new để khởi tại một ứng dụng mới.

Tạo một model

Tiếp theo, tôi sẽ tạo một model mới. Hướng dẫn của rails rất chi tiết, vì vậy gõ rails generate (hoặc dùng phím tắt là rails g) hiển thị tất cả các giá trị khởi tạo.

rails g model Movie title director storyline:text watched_on:date

Ở đấy tôi khởi tạo title và directory như một string (loại dữ liệu mặc định nếu không chỉ định rõ), storyline như text, và watched_on là date (khi muốn khởi tạo dates không phải là datetimes thì chúng ta thêm đuôi on vào trường dữ liệu).
Rails sẽ khởi tạo một migrate phù hợp với hệ quản trị dữ liệu mặc định là SQLite. Migrations được lưu trong db/migrations. Hãy xem trông nó như thế nào:

Rất là đơn giản. Điều đáng chú ý duy nhất là các câu lệnh thời gian: nó sẽ tự động khởi tạo các trường createdatupdatedat, rất là hữu ích. Hãy xem nó chạy:

Vì vậy bây giờ Rails đã thực sự tạo ra một bảng. Trong trường hợp có lỗi, thì bạn hoàn toàn có thể quay lại trạng thái trước:

rails db:rollback

Lệnh này có trường tự chọn step để quay lại nhiều phiên bản trước nếu cần.
Vì vậy bây giờ bảng đã được tạo, hãy cùng xem schema trông như thế nào trong db/schema.rb:

Tệp này chứa tất cả các entire trong cơ sở dữ liệu như chúng ta chạy nhiều migrations.

Lệnh rake

Làm thế nào để chúng ta biết có những lệnh rake nào? Bằng cách sử dụng tham số -T chúng ta có thể thấy danh sách những câu lệnh đó:

rake -T

Bạn có thể giới hạn bằng các sử dụng namesapce, chẳng hạn như db:

rake -T db

Tạo một vài seeds

Bây giời chúng ta sẽ đi đến phần thú vị của bài viết!. Mở db/seeds.rb và paste đoạn sau vào:

Movie.destroy_all
 
Movie.create!([{
  title: "Ant-Man",
  director: "Peyton Reed",
  storyline: "Armed with the astonishing ability to shrink in scale but increase in strength, con-man Scott Lang must embrace his inner-hero and help his mentor, Dr. Hank Pym, protect the secret behind his spectacular Ant-Man suit from a new generation of towering threats. Against seemingly insurmountable obstacles, Pym and Lang must plan and pull off a heist that will save the world.",
  watched_on: 5.days.ago
},
{
  title: "Pixels",
  director: "Chris Columbus",
  storyline: "When aliens misinterpret video feeds of classic arcade games as a declaration of war, they attack the Earth in the form of the video games.",
  watched_on: 3.days.ago
},
{
  title: "Terminator Genisys",
  director: "Alan Taylor",
  storyline: "When John Connor, leader of the human resistance, sends Sgt. Kyle Reese back to 1984 to protect Sarah Connor and safeguard the future, an unexpected turn of events creates a fractured timeline. Now, Sgt. Reese finds himself in a new and unfamiliar version of the past, where he is faced with unlikely allies, including the Guardian, dangerous new enemies, and an unexpected new mission: To reset the future...",
  watched_on: 10.days.ago
}])
 
p "Created #{Movie.count} movies"

Đầu tiên chúng sẽ destroy tất cả các movies để làm sạch cơ sở dữ liêu, và thêm 3 movies ở trong một mảng vào phương thức create. Tệp seeds dùng Rails ActiveSupport, vì vậy chúng ta có thể sử dụng các câu lệnh Ruby như là day.ago để định nghĩa ngày. Ở cuối cùng tôi nhận được phản hồi về tổng số movies được tạo. Hãy chạy thử nó!

$rake db:seed
"Created 3 movies"

Bạn có thể chạy câu lệnh này nhiều lần nếu bạn cần và điều này sẽ không xảy ra vấn đề gì vì có câu lệnh destroy ở dòng đầu tiên. Để kiểm tra chúng ta có thể sử dụng Rails runner:

$rails runner 'p Movie.pluck :title'
["Ant-Man", "Pixels", "Terminator Genisys"]

Tùy chỉnh rake task để tạo dữ liệu quan trọng

Tất cả các seeds của chúng ta chứa trong cơ cở dữ liệu ở development, không phải là dữ liệu quan trọng cho production sử dụng. Vì vậy, seeds của production không giống như cái chúng ta đã làm. Để seed cho dữ liệu quan trọng tốt hơn chúng ta nên tùy chỉnh rake task. Hãy cùng tạo model genres:

rails g model Genre name
...
rake db:migrate
...
rails g task movies seed_genres
      create  lib/tasks/movies.rake

Nó tạo ra một tệp movies rake trong thư mục lib chứa seed_genres task (bạn có thể thêm nhiều hơn từ command line).

namespace :movies do
  desc "Seeds genres"
  task seed_genres: :environment do
    Genre.create!([{
      name: "Action"
    },
    {
      name: "Sci-Fi"
    },
    {
      name: "Adventure"
    }])
  end
 
  p "Created #{Genre.count} genres"
end

Liệt kê danh sách câu lệnh rake:

$ rake -T movies
rake movies:seed_genres  # Seeds genres
$ rake movies:seed_genres
"Created 3 genres"

Tạo seeds bằng cách sử dụng console

Console rất hữu ích để bạn có thể "chơi" với dữ liệu của bạn. Hãy bắt đầu bằng:

$ rails c

Bạn có biết rằng bạn có thể tải từ bên trong seed? Bạn không cần chạy rake nữa. Hãy thử:

	
Rails.application.load_seed

Playing with data using the console sandbox

Thỉnh thoảng bạn sẽ cần chạy thử một số câu lệnh phá hủy trên môi trường development hoặc production, nhưng không ảnh hưởng đến dữ liệu thực của bạn. Đó là một thứ gì đó giống như chế độ an toàn, nơi bạn có thể làm bất kỳ điều gì bạn thích và sau đó quay lại trạng thái an toàn trước đó.
Để truy cập chế độ này bạn chỉ cần chạy rails c --sandbox. Sau đó, bạn có thể làm một vài điều như:

  • Movie.update_all(title: 'Foo') để update tất cả các title của movies
  • Movie.first.title sẽ hiển thị "Foo"

Nếu bạn muốn thoát ra console và chạy nó lại lần nữa để kiểm tra title của movie đầu tiên, nó sẽ hiển thị title ban đầu của nó. Điều này thực sự hữu ích trong môi trường phát triển, chẳng hạn như người dùng cập nhập hồ sơ của mình, anh ta sẽ gặp một số lỗi lạ. CHúng ta có thể có gắng tái tạo lỗi đó bằng cách sử dụng chế độ sandbox, mà không ảnh hướng tới ứng dụng.

Tải thêm seed bằng Faker

Nếu bạn cần 100 movie bạn có thể thay thế tệp của mình bằng tệp này:

Movie.destroy_all
 
100.times do |index|
  Movie.create!(title: "Title #{index}",
                director: "Director #{index}",
                storyline: "Storyline #{index}",
                watched_on: index.days.ago)
end
 
p "Created #{Movie.count} movies"

Nhưng trông tất cả dữ liệu được tạo ra không được thật tế và tất cả chúng dường như giống nhau:

$ rails runner 'p Movie.select(:title, :director, :storyline).last'
#<Movie id: nil, title: "Title 99", director: "Director 99", storylin

Bây giờ là lúc sử dụng Faker, một gem dùng để tạo ngẫu nhiên các giá trị. Thêm nó vào trong group development ở trong Gemfile:

group :development, :test do
  # ...
 
  gem 'faker'
end

Chạy bundle install và sử dụng seeds:

Movie.destroy_all
 
100.times do |index|
  Movie.create!(title: Faker::Lorem.sentence(3, false, 0).chop,
                director: Faker::Name.name,
                storyline: Faker::Lorem.paragraph,
                watched_on: Faker::Time.between(4.months.ago, 1.week.ago))
end
 
p "Created #{Movie.count} movies"

Kiểm tra lại một lần nữa:

$ rails runner 'p Movie.select(:title, :director, :storyline, :watched_on).last'
#<Movie id: nil, title: "Minus perferendis delectus", director

Tốt hơn rồi ^^

Tổng kết

Tạo seed cho ứng dụng của bạn khi phát triển rất quan trọng bởi vì bạn sẽ cảm thấy như chúng ta có dữ liệu thực. Thật thú vị khi xem nó trông như thế nào vì dữ liệu có độ dài ngẫu nhiên.
Ngoài ra, biết các công cụ có sẵn để làm việc với seed cho chúng ta cảm thấy thoải mái và có năng suất cao hơn, vì vậy bạn nên đầu tư một chút thời gian để học và thực hành.

Bài viết được dịch từ https://davidmles.com/seeding-database-rails/ ^^