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)
いろんなメソッドを使いますが、どれも単純なものなので、
試してみてください。
改善点あれば是非ご指摘ください。