railsコマンドでファイル名を指定してseedデータを入れる方法
バージョン
テストデータやマスタデータの挿入
Railsにはデフォルトでdb/seeds.rbというファイルが生成されていて、
ここにインサート文などを書いておくと、
rails db:seedでデータをDBに挿入してくれます。
指定したseedファイルだけを挿入
ただ、特定のデータだけ挿入したいというときには、
毎回、seeds.rbを書き換えないといけません。
1回だけならまだいいですが、間隔をおいて何回も挿入しなければいけないときは、だいぶめんどくさいです。
そんなときのために、このような
rails db:seed_from_file SEED_FILENAME='seeds/ファイル名'
railsコマンドの引数でファイル名を渡して、seedデータを挿入する方法を書いていきます。
なお、ディレクトリの構成はこんな感じです。
root/
lib/
tasks/
db.rake
db/
seeds/
01_sample_seeds.rb
02_sample_seeds.rb
03_sample_seeds.rb
挿入したいテストデータをdb/seeds配下のファイルに記載している想定です。
タスクファイルを作成する
rails g task ファイル名でタスクファイルを作成することができます。
今回は、rails g task dbとコマンドを叩き、lib/tasks/db.rakeを作成しました。
どのseedファイルを実行するか記載
タスクファイルが作成できたら、中身を書いていきます。
今回叩きたいコマンドrails db:seed_from_file SEED_FILENAME='seeds/03_sample_seeds.rb'に合わせて書いていきます。
今回はこのような感じで書いてみました。
namespace :db do desc 'Load the seed data from SEED_FILENAME' task :seed_from_file => 'db:abort_if_pending_migrations' do seed_file = File.join(Rails.root, 'db', ENV['SEED_FILENAME']) if File.exist?(seed_file) puts "seeding -- #{ENV['SEED_FILENAME']}" load(seed_file) else puts "the seed file does not exist." end end end
以下から各メソッドの解説です。
・namespace
apiのルーティングなどでよく使われるnamespaceメソッドですが、
ここではコマンドを叩くときのコマンド名みたいなものです。
これをネストしていくとコマンドもネストされます。
namespace :apple do namespace :banana do namespace :orange do task :eat do #省略 end end end end
であればrails apple:banana:orange:eat
という風なコマンドになります。
・desc
メソッドの説明文になります。
rails -Tでタスクを表示したときに一緒に説明文が表示されます。
・task
実行するメソッド名です。
成功していないマイグレーションがあるとデータを入れるのはよくないので、先に'db:abort_if_pending_migrations'を実行するようにしています。
・File.join
seedファイルまでのパスを生成するメソッドです。
コマンドの引数であるSEED_FILENAMEからファイル名を受け取り、実行するファイルを特定します。
Rails.root, 'db'と記載しておくことで、コマンドからの引数であるファイルまでのパスを省略できます。
load(seed_file)で実行しています。
まとめ
僕のカップル専用家計簿アプリでは、
月毎に合計値や前月などを計算しています。
そのため、月が変わると計算する値がなく、
真っ白になってしまうページがあり、
実装するときに不便になるので、
今回のようなテストデータを入れられるタスクを作りました。
(まだ毎月挿入するシードデータを作ってないですがw)
いろんなメソッドを使いますが、どれも単純なものなので、
試してみてください。
改善点あれば是非ご指摘ください。